~ubuntu-branches/debian/wheezy/ghostscript/wheezy

« back to all changes in this revision

Viewing changes to base/gdevmpla.c

  • Committer: Package Import Robot
  • Author(s): Jonas Smedegaard
  • Date: 2012-02-10 19:27:35 UTC
  • mfrom: (1.2.7)
  • Revision ID: package-import@ubuntu.com-20120210192735-itmbfs6nfl8t9qm8
Tags: 9.05~dfsg-1
* New upstream release.
* Update copyright file:
  + Improve Copyright shortnames:
    - BSD → BSD-3-Clause
    - MIT~Open → NTP~Open
    - MIT~WSU → NTP~WSU
    - MIT~Lucent → NTP~Lucent
    - other-Adobe → BSD-3-Clause~Adobe
  + Fix merge double Files-Excluded, and list globbing before specific
    files.
  + Quote licenses in Comment fields.
  + Drop duplicate Comment fields.
  + Fix refer to license shortname AFPL~AFPL (not AFPL).
  + Extend copyright years.
  + Add new Files section, Apache-2.0 licensed (TrueType file, not
    linked code so not challenging GPL).
  + Drop a few Files sections and a License section.
* strip convenience library openjpeg from upstream source.
* Imported Upstream version 9.05~dfsg
* Drop patches 020110819 and 1001, applied upstream.
* Explicitly disable use of openjpeg: Now preferred if available but
  requires patching for ICC and CMYK support.
* Update symbols file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
declare_mem_procs(mem_planar_copy_mono, mem_planar_copy_color, mem_planar_fill_rectangle);
29
29
static dev_proc_copy_color(mem_planar_copy_color_24to8);
30
30
static dev_proc_copy_color(mem_planar_copy_color_4to1);
31
 
static dev_proc_copy_plane(mem_planar_copy_plane);
 
31
static dev_proc_copy_planes(mem_planar_copy_planes);
32
32
static dev_proc_strip_tile_rectangle(mem_planar_strip_tile_rectangle);
33
33
static dev_proc_strip_copy_rop(mem_planar_strip_copy_rop);
 
34
static dev_proc_strip_copy_rop2(mem_planar_strip_copy_rop2);
34
35
static dev_proc_get_bits_rectangle(mem_planar_get_bits_rectangle);
35
36
 
 
37
/* It's a bit nasty to have to fork the planar dev_spec_op like this, but
 
38
 * the forwarding nature of the device means that the function pointer test
 
39
 * for the map_cmyk_color call fails if we let it fall through to the
 
40
 * default device. */
36
41
static int
37
42
mem_planar_dev_spec_op(gx_device *pdev, int dev_spec_op,
38
43
                       void *data, int size)
42
47
    return gx_default_dev_spec_op(pdev, dev_spec_op, data, size);
43
48
}
44
49
 
 
50
static int
 
51
mem_planar_dev_spec_op_cmyk4(gx_device *pdev, int dev_spec_op,
 
52
                             void *data, int size)
 
53
{
 
54
    if (dev_spec_op == gxdso_is_native_planar)
 
55
        return 1;
 
56
    if (dev_spec_op == gxdso_is_std_cmyk_1bit)
 
57
        return 1;
 
58
    return gx_default_dev_spec_op(pdev, dev_spec_op, data, size);
 
59
}
 
60
 
45
61
/*
46
62
 * Set up a planar memory device, after calling gs_make_mem_device but
47
63
 * before opening the device.  The pre-existing device provides the color
95
111
        set_dev_proc(mdev, copy_alpha, dev_proc(mdproto, copy_alpha));
96
112
        set_dev_proc(mdev, strip_tile_rectangle, dev_proc(mdproto, strip_tile_rectangle));
97
113
        set_dev_proc(mdev, strip_copy_rop, dev_proc(mdproto, strip_copy_rop));
 
114
        set_dev_proc(mdev, strip_copy_rop2, dev_proc(mdproto, strip_copy_rop2));
98
115
        set_dev_proc(mdev, get_bits_rectangle, dev_proc(mdproto, get_bits_rectangle));
99
116
    } else {
100
117
        set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle);
101
118
        set_dev_proc(mdev, copy_mono, mem_planar_copy_mono);
 
119
        set_dev_proc(mdev, dev_spec_op, mem_planar_dev_spec_op);
102
120
        if ((mdev->color_info.depth == 24) &&
103
121
            (mdev->num_planes == 3) &&
104
122
            (mdev->planes[0].depth == 8) && (mdev->planes[0].shift == 16) &&
110
128
                 (mdev->planes[0].depth == 1) && (mdev->planes[0].shift == 3) &&
111
129
                 (mdev->planes[1].depth == 1) && (mdev->planes[1].shift == 2) &&
112
130
                 (mdev->planes[2].depth == 1) && (mdev->planes[2].shift == 1) &&
113
 
                 (mdev->planes[3].depth == 1) && (mdev->planes[3].shift == 0))
 
131
                 (mdev->planes[3].depth == 1) && (mdev->planes[3].shift == 0)) {
114
132
            set_dev_proc(mdev, copy_color, mem_planar_copy_color_4to1);
115
 
        else
 
133
            set_dev_proc(mdev, dev_spec_op, mem_planar_dev_spec_op_cmyk4);
 
134
        } else
116
135
            set_dev_proc(mdev, copy_color, mem_planar_copy_color);
117
136
        set_dev_proc(mdev, copy_alpha, gx_default_copy_alpha);
118
 
        set_dev_proc(mdev, copy_plane, mem_planar_copy_plane);
 
137
        set_dev_proc(mdev, copy_planes, mem_planar_copy_planes);
119
138
        set_dev_proc(mdev, strip_tile_rectangle, mem_planar_strip_tile_rectangle);
120
139
        set_dev_proc(mdev, strip_copy_rop, mem_planar_strip_copy_rop);
 
140
        set_dev_proc(mdev, strip_copy_rop2, mem_planar_strip_copy_rop2);
121
141
        set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle);
122
 
        set_dev_proc(mdev, dev_spec_op, mem_planar_dev_spec_op);
123
142
    }
124
143
    return 0;
125
144
}
152
171
   msp.line_ptrs = mdev->line_ptrs)
153
172
/* Previous versions of MEM_SET_PARAMS calculated raster as
154
173
 * bitmap_raster(mdev->width * plane_depth), but this restricts us to
155
 
 * non interleaved frame buffers. */
 
174
 * non interleaved frame buffers. Now we calculate it from the difference
 
175
 * between the first 2 line pointers; this clearly only works if there are
 
176
 * at least 2 line pointers to use. Otherwise, we fall back to the old
 
177
 * method.
 
178
 */
 
179
/* FIXME: Find a nicer way of calculating raster. */
156
180
#define MEM_SET_PARAMS(mdev, plane_depth)\
157
181
  (mdev->color_info.depth = plane_depth, /* maybe not needed */\
158
182
   mdev->base = mdev->line_ptrs[0],\
159
 
   mdev->raster = mdev->line_ptrs[1]-mdev->line_ptrs[0])
 
183
   mdev->raster = (mdev->height > 1 ? mdev->line_ptrs[1]-mdev->line_ptrs[0] : bitmap_raster(mdev->width * plane_depth)))
160
184
#define MEM_RESTORE_PARAMS(mdev, msp)\
161
185
  (mdev->color_info.depth = msp.depth,\
162
186
   mdev->base = msp.base,\
297
321
}
298
322
 
299
323
/* Copy color: Special case the 4 -> 1+1+1+1 case. */
 
324
/* Two versions of this routine; the first does bit comparisons. This should
 
325
 * work well on architectures with small cache and conditional execution
 
326
 * (such as ARM). Hurts on x86 due to the ifs in the loop all causing small
 
327
 * skips ahead that defeat the branch predictor.
 
328
 * Second version uses a table lookup; 1K of table is nothing on x86, and
 
329
 * so this runs much faster. */
 
330
#ifdef PREFER_ALTERNATIION_TO_TABLES
300
331
static int
301
332
mem_planar_copy_color_4to1(gx_device * dev, const byte * base, int sourcex,
302
333
                            int sraster, gx_bitmap_id id,
314
345
    uint plane_raster = bitmap_raster(w);
315
346
    int br, bw, bh, cx, cy, cw, ch, ix, iy;
316
347
 
 
348
#ifdef MEMENTO
 
349
    /* Pacify valgrind */
 
350
    memset(buf0.l, 0, sizeof(ulong) * BUF_LONGS);
 
351
    memset(buf1.l, 0, sizeof(ulong) * BUF_LONGS);
 
352
    memset(buf2.l, 0, sizeof(ulong) * BUF_LONGS);
 
353
    memset(buf3.l, 0, sizeof(ulong) * BUF_LONGS);
 
354
#endif
 
355
 
317
356
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
318
357
    MEM_SAVE_PARAMS(mdev, save);
319
358
    MEM_SET_PARAMS(mdev, 1);
470
509
    MEM_RESTORE_PARAMS(mdev, save);
471
510
    return 0;
472
511
}
 
512
#else
 
513
 
 
514
static bits32 expand_4to1[256] =
 
515
{
 
516
0x00000000,0x00000001,0x00000100,0x00000101,
 
517
0x00010000,0x00010001,0x00010100,0x00010101,
 
518
0x01000000,0x01000001,0x01000100,0x01000101,
 
519
0x01010000,0x01010001,0x01010100,0x01010101,
 
520
0x00000002,0x00000003,0x00000102,0x00000103,
 
521
0x00010002,0x00010003,0x00010102,0x00010103,
 
522
0x01000002,0x01000003,0x01000102,0x01000103,
 
523
0x01010002,0x01010003,0x01010102,0x01010103,
 
524
0x00000200,0x00000201,0x00000300,0x00000301,
 
525
0x00010200,0x00010201,0x00010300,0x00010301,
 
526
0x01000200,0x01000201,0x01000300,0x01000301,
 
527
0x01010200,0x01010201,0x01010300,0x01010301,
 
528
0x00000202,0x00000203,0x00000302,0x00000303,
 
529
0x00010202,0x00010203,0x00010302,0x00010303,
 
530
0x01000202,0x01000203,0x01000302,0x01000303,
 
531
0x01010202,0x01010203,0x01010302,0x01010303,
 
532
0x00020000,0x00020001,0x00020100,0x00020101,
 
533
0x00030000,0x00030001,0x00030100,0x00030101,
 
534
0x01020000,0x01020001,0x01020100,0x01020101,
 
535
0x01030000,0x01030001,0x01030100,0x01030101,
 
536
0x00020002,0x00020003,0x00020102,0x00020103,
 
537
0x00030002,0x00030003,0x00030102,0x00030103,
 
538
0x01020002,0x01020003,0x01020102,0x01020103,
 
539
0x01030002,0x01030003,0x01030102,0x01030103,
 
540
0x00020200,0x00020201,0x00020300,0x00020301,
 
541
0x00030200,0x00030201,0x00030300,0x00030301,
 
542
0x01020200,0x01020201,0x01020300,0x01020301,
 
543
0x01030200,0x01030201,0x01030300,0x01030301,
 
544
0x00020202,0x00020203,0x00020302,0x00020303,
 
545
0x00030202,0x00030203,0x00030302,0x00030303,
 
546
0x01020202,0x01020203,0x01020302,0x01020303,
 
547
0x01030202,0x01030203,0x01030302,0x01030303,
 
548
0x02000000,0x02000001,0x02000100,0x02000101,
 
549
0x02010000,0x02010001,0x02010100,0x02010101,
 
550
0x03000000,0x03000001,0x03000100,0x03000101,
 
551
0x03010000,0x03010001,0x03010100,0x03010101,
 
552
0x02000002,0x02000003,0x02000102,0x02000103,
 
553
0x02010002,0x02010003,0x02010102,0x02010103,
 
554
0x03000002,0x03000003,0x03000102,0x03000103,
 
555
0x03010002,0x03010003,0x03010102,0x03010103,
 
556
0x02000200,0x02000201,0x02000300,0x02000301,
 
557
0x02010200,0x02010201,0x02010300,0x02010301,
 
558
0x03000200,0x03000201,0x03000300,0x03000301,
 
559
0x03010200,0x03010201,0x03010300,0x03010301,
 
560
0x02000202,0x02000203,0x02000302,0x02000303,
 
561
0x02010202,0x02010203,0x02010302,0x02010303,
 
562
0x03000202,0x03000203,0x03000302,0x03000303,
 
563
0x03010202,0x03010203,0x03010302,0x03010303,
 
564
0x02020000,0x02020001,0x02020100,0x02020101,
 
565
0x02030000,0x02030001,0x02030100,0x02030101,
 
566
0x03020000,0x03020001,0x03020100,0x03020101,
 
567
0x03030000,0x03030001,0x03030100,0x03030101,
 
568
0x02020002,0x02020003,0x02020102,0x02020103,
 
569
0x02030002,0x02030003,0x02030102,0x02030103,
 
570
0x03020002,0x03020003,0x03020102,0x03020103,
 
571
0x03030002,0x03030003,0x03030102,0x03030103,
 
572
0x02020200,0x02020201,0x02020300,0x02020301,
 
573
0x02030200,0x02030201,0x02030300,0x02030301,
 
574
0x03020200,0x03020201,0x03020300,0x03020301,
 
575
0x03030200,0x03030201,0x03030300,0x03030301,
 
576
0x02020202,0x02020203,0x02020302,0x02020303,
 
577
0x02030202,0x02030203,0x02030302,0x02030303,
 
578
0x03020202,0x03020203,0x03020302,0x03020303,
 
579
0x03030202,0x03030203,0x03030302,0x03030303
 
580
};
 
581
 
 
582
static int
 
583
mem_planar_copy_color_4to1(gx_device * dev, const byte * base, int sourcex,
 
584
                            int sraster, gx_bitmap_id id,
 
585
                            int x, int y, int w, int h)
 
586
{
 
587
    gx_device_memory * const mdev = (gx_device_memory *)dev;
 
588
#define BUF_LONGS 100   /* arbitrary, >= 1 */
 
589
#define BUF_BYTES (BUF_LONGS * ARCH_SIZEOF_LONG)
 
590
    union b_ {
 
591
        ulong l[BUF_LONGS];
 
592
        byte b[BUF_BYTES];
 
593
    } buf0, buf1, buf2, buf3;
 
594
    mem_save_params_t save;
 
595
    const gx_device_memory *mdproto = gdev_mem_device_for_bits(1);
 
596
    uint plane_raster = bitmap_raster(w);
 
597
    int br, bw, bh, cx, cy, cw, ch, ix, iy;
 
598
 
 
599
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
 
600
    MEM_SAVE_PARAMS(mdev, save);
 
601
    MEM_SET_PARAMS(mdev, 1);
 
602
    if (plane_raster > BUF_BYTES) {
 
603
        br = BUF_BYTES;
 
604
        bw = BUF_BYTES<<3;
 
605
        bh = 1;
 
606
    } else {
 
607
        br = plane_raster;
 
608
        bw = w;
 
609
        bh = BUF_BYTES / plane_raster;
 
610
    }
 
611
    for (cy = y; cy < y + h; cy += ch) {
 
612
        ch = min(bh, y + h - cy);
 
613
        for (cx = x; cx < x + w; cx += cw) {
 
614
            int sx = sourcex + cx - x;
 
615
            const byte *source_base = base + sraster * (cy - y) + (sx>>1);
 
616
 
 
617
            cw = min(bw, x + w - cx);
 
618
            if ((sx & 1) == 0) {
 
619
                for (iy = 0; iy < ch; ++iy) {
 
620
                    const byte *sptr = source_base;
 
621
                    byte *dptr0 = buf0.b + br * iy;
 
622
                    byte *dptr1 = buf1.b + br * iy;
 
623
                    byte *dptr2 = buf2.b + br * iy;
 
624
                    byte *dptr3 = buf3.b + br * iy;
 
625
                    int roll = 6;
 
626
                    int cmyk = 0;
 
627
                    ix = cw;
 
628
                    do {
 
629
                        cmyk |= expand_4to1[*sptr++]<<roll;
 
630
                        roll -= 2;
 
631
                        if (roll < 0) {
 
632
                            *dptr0++ = cmyk>>24;
 
633
                            *dptr1++ = cmyk>>16;
 
634
                            *dptr2++ = cmyk>>8;
 
635
                            *dptr3++ = cmyk;
 
636
                            cmyk = 0;
 
637
                            roll = 6;
 
638
                        }
 
639
                        ix -= 2;
 
640
                    } while (ix > 0);
 
641
                    if (roll != 6) {
 
642
                        *dptr0++ = cmyk>>24;
 
643
                        *dptr1++ = cmyk>>16;
 
644
                        *dptr2++ = cmyk>>8;
 
645
                        *dptr3++ = cmyk;
 
646
                    }
 
647
                    source_base += sraster;
 
648
                }
 
649
            } else {
 
650
                for (iy = 0; iy < ch; ++iy) {
 
651
                    const byte *sptr = source_base;
 
652
                    byte *dptr0 = buf0.b + br * iy;
 
653
                    byte *dptr1 = buf1.b + br * iy;
 
654
                    byte *dptr2 = buf2.b + br * iy;
 
655
                    byte *dptr3 = buf3.b + br * iy;
 
656
                    int roll = 7;
 
657
                    int cmyk = 0;
 
658
                    byte b = *sptr++ & 0x0f;
 
659
                    ix = cw;
 
660
                    goto loop_entry;
 
661
                    do {
 
662
                        b = *sptr++;
 
663
                        roll -= 2;
 
664
                        if (roll < 0)
 
665
                        {
 
666
                            cmyk |= expand_4to1[b & 0xf0]>>1;
 
667
                            *dptr0++ = cmyk>>24;
 
668
                            *dptr1++ = cmyk>>16;
 
669
                            *dptr2++ = cmyk>>8;
 
670
                            *dptr3++ = cmyk;
 
671
                            cmyk = 0;
 
672
                            roll = 7;
 
673
                            b &= 0x0f;
 
674
                        }
 
675
loop_entry:
 
676
                        cmyk |= expand_4to1[b]<<roll;
 
677
                        ix -= 2;
 
678
                    } while (ix >= 0); /* ix == -2 means 1 extra done */
 
679
                    if ((ix == -2) && (roll == 7)) {
 
680
                        /* We did an extra one, and it was the last thing
 
681
                         * we did. Nothing to store. */
 
682
                    } else {
 
683
                        /* Flush the stored bytes */
 
684
                        *dptr0++ = cmyk>>24;
 
685
                        *dptr1++ = cmyk>>16;
 
686
                        *dptr2++ = cmyk>>8;
 
687
                        *dptr3++ = cmyk;
 
688
                    }
 
689
                    source_base += sraster;
 
690
                }
 
691
            }
 
692
            dev_proc(mdproto, copy_mono)
 
693
                        (dev, buf0.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
 
694
                         (gx_color_index)0, (gx_color_index)1);
 
695
            mdev->line_ptrs += mdev->height;
 
696
            dev_proc(mdproto, copy_mono)
 
697
                        (dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
 
698
                         (gx_color_index)0, (gx_color_index)1);
 
699
            mdev->line_ptrs += mdev->height;
 
700
            dev_proc(mdproto, copy_mono)
 
701
                        (dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
 
702
                         (gx_color_index)0, (gx_color_index)1);
 
703
            mdev->line_ptrs += mdev->height;
 
704
            dev_proc(mdproto, copy_mono)
 
705
                        (dev, buf3.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
 
706
                         (gx_color_index)0, (gx_color_index)1);
 
707
            mdev->line_ptrs -= 3*mdev->height;
 
708
        }
 
709
    }
 
710
    MEM_RESTORE_PARAMS(mdev, save);
 
711
    return 0;
 
712
}
 
713
#endif
473
714
 
474
715
/* Copy a color bitmap. */
475
716
/* This is slow and messy. */
577
818
 
578
819
/* Copy a given bitmap into a bitmap. */
579
820
static int
580
 
mem_planar_copy_plane(gx_device * dev, const byte * base, int sourcex,
581
 
                      int sraster, gx_bitmap_id id,
582
 
                      int x, int y, int w, int h, int plane)
 
821
mem_planar_copy_planes(gx_device * dev, const byte * base, int sourcex,
 
822
                       int sraster, gx_bitmap_id id,
 
823
                       int x, int y, int w, int h, int plane_height)
583
824
{
584
825
    gx_device_memory * const mdev = (gx_device_memory *)dev;
585
826
    int plane_depth;
586
827
    mem_save_params_t save;
587
828
    const gx_device_memory *mdproto;
588
 
    int code;
 
829
    int code = 0;
 
830
    int plane;
589
831
 
590
 
    if ((plane < 0) || (plane >= mdev->num_planes))
591
 
        return gs_error_rangecheck;
592
832
    MEM_SAVE_PARAMS(mdev, save);
593
 
    mdev->line_ptrs += mdev->height * plane;
594
 
    plane_depth = mdev->planes[plane].depth;
595
 
    mdproto = gdev_mem_device_for_bits(plane_depth);
596
 
    if (plane_depth == 1)
597
 
        code = dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id,
598
 
                                            x, y, w, h,
599
 
                                            (gx_color_index)0,
600
 
                                            (gx_color_index)1);
601
 
    else
602
 
        code = dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster,
603
 
                                             id, x, y, w, h);
 
833
    for (plane = 0; plane < mdev->num_planes; plane++)
 
834
    {
 
835
        plane_depth = mdev->planes[plane].depth;
 
836
        mdproto = gdev_mem_device_for_bits(plane_depth);
 
837
        if (plane_depth == 1)
 
838
            code = dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id,
 
839
                                                x, y, w, h,
 
840
                                                (gx_color_index)0,
 
841
                                                (gx_color_index)1);
 
842
        else
 
843
            code = dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster,
 
844
                                                 id, x, y, w, h);
 
845
        base += sraster * plane_height;
 
846
        mdev->line_ptrs += mdev->height;
 
847
    }
604
848
    MEM_RESTORE_PARAMS(mdev, save);
605
849
    return code;
606
850
}
653
897
}
654
898
 
655
899
static int
656
 
mem_planar_strip_copy_rop(gx_device * dev,
657
 
                          const byte * sdata, int sourcex, uint sraster,
658
 
                          gx_bitmap_id id, const gx_color_index * scolors,
659
 
                          const gx_strip_bitmap * textures,
660
 
                          const gx_color_index * tcolors,
661
 
                          int x, int y, int width, int height,
662
 
                          int phase_x, int phase_y,
663
 
                          gs_logical_operation_t lop)
664
 
{
665
 
    gx_device_memory * const mdev = (gx_device_memory *)dev;
 
900
planar_cmyk4bit_strip_copy_rop(gx_device_memory * mdev,
 
901
                               const byte * srow, int sourcex, uint sraster,
 
902
                               gx_bitmap_id id, const gx_color_index * scolors,
 
903
                               const gx_strip_bitmap * textures,
 
904
                               const gx_color_index * tcolors,
 
905
                               int x, int y, int width, int height,
 
906
                               int phase_x, int phase_y,
 
907
                               gs_logical_operation_t lop)
 
908
{
 
909
    gs_rop3_t rop = (gs_rop3_t)lop;
 
910
    uint draster = mdev->raster;
 
911
    int line_count;
 
912
    byte *cdrow, *mdrow, *ydrow, *kdrow;
 
913
    byte lmask, rmask;
 
914
    rop_proc cproc, mproc, yproc;
 
915
    int dbit;
 
916
    int cscolor, mscolor, yscolor, kscolor;
 
917
    int ctcolor, mtcolor, ytcolor, ktcolor;
 
918
    int constant_s = 0;
 
919
 
 
920
    /* Modify the raster operation according to the source palette. */
 
921
    fit_copy(mdev, srow, sourcex, sraster, id, x, y, width, height);
 
922
 
 
923
    /* This function assumes constant (or unused) scolors and tcolors */
 
924
    if (scolors)
 
925
    {
 
926
        if (scolors[0] == scolors[1]) {
 
927
            kscolor = ((scolors[0] & 1) ? -1 : 0);
 
928
            cscolor = ((scolors[0] & 8) ? -1 : 0) | kscolor;
 
929
            mscolor = ((scolors[0] & 4) ? -1 : 0) | kscolor;
 
930
            yscolor = ((scolors[0] & 2) ? -1 : 0) | kscolor;
 
931
            constant_s = 1;
 
932
        } else {
 
933
            kscolor =  (scolors[0] & 1)     | ((scolors[1] & 1)<<1);
 
934
            cscolor = ((scolors[0] & 8)>>3) | ((scolors[1] & 8)>>2) | kscolor;
 
935
            mscolor = ((scolors[0] & 4)>>2) | ((scolors[1] & 4)>>1) | kscolor;
 
936
            yscolor = ((scolors[0] & 2)>>1) |  (scolors[1] & 2)     | kscolor;
 
937
            switch (cscolor) {
 
938
                case 0:
 
939
                    cproc = rop_proc_table[rop3_know_S_0(rop)];
 
940
                    break;
 
941
                case 1:
 
942
                    cproc = rop_proc_table[rop3_invert_S(rop)];
 
943
                    break;
 
944
                case 2:
 
945
                    cproc = rop_proc_table[rop];
 
946
                    break;
 
947
                default: /* 3 */
 
948
                    cproc = rop_proc_table[rop3_know_S_1(rop)];
 
949
                    break;
 
950
            }
 
951
            switch (mscolor) {
 
952
                case 0:
 
953
                    mproc = rop_proc_table[rop3_know_S_0(rop)];
 
954
                    break;
 
955
                case 1:
 
956
                    mproc = rop_proc_table[rop3_invert_S(rop)];
 
957
                    break;
 
958
                case 2:
 
959
                    mproc = rop_proc_table[rop];
 
960
                    break;
 
961
                default: /* 3 */
 
962
                    mproc = rop_proc_table[rop3_know_S_1(rop)];
 
963
                    break;
 
964
            }
 
965
            switch (yscolor) {
 
966
                case 0:
 
967
                    yproc = rop_proc_table[rop3_know_S_0(rop)];
 
968
                    break;
 
969
                case 1:
 
970
                    yproc = rop_proc_table[rop3_invert_S(rop)];
 
971
                    break;
 
972
                case 2:
 
973
                    yproc = rop_proc_table[rop];
 
974
                    break;
 
975
                default: /* 3 */
 
976
                    yproc = rop_proc_table[rop3_know_S_1(rop)];
 
977
                    break;
 
978
            }
 
979
        }
 
980
    }
 
981
    if (tcolors)
 
982
    {
 
983
        ktcolor = ((tcolors[0] & 1) ? -1 : 0);
 
984
        ctcolor = ((tcolors[0] & 8) ? -1 : 0) | ktcolor;
 
985
        mtcolor = ((tcolors[0] & 4) ? -1 : 0) | ktcolor;
 
986
        ytcolor = ((tcolors[0] & 2) ? -1 : 0) | ktcolor;
 
987
    }
 
988
 
 
989
    /* Set up transfer parameters. */
 
990
    line_count = height;
 
991
    if (lop_uses_T(lop) && (tcolors == NULL)) { /* && (textures != NULL) */
 
992
        /* Pixmap textures. For now we'll only get into this routine if
 
993
         * textures is a pixmap (or constant, in which case we'll do it
 
994
         * below). */
 
995
        int ty;
 
996
        uint traster;
 
997
 
 
998
/* Calculate the X offset for a given Y value, */
 
999
/* taking shift into account if necessary. */
 
1000
#define x_offset(px, ty, textures)\
 
1001
  ((textures)->shift == 0 ? (px) :\
 
1002
   (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
 
1003
 
 
1004
        cdrow = scan_line_base(mdev, y);
 
1005
        mdrow = cdrow + mdev->height * draster;
 
1006
        ydrow = mdrow + mdev->height * draster;
 
1007
        kdrow = ydrow + mdev->height * draster;
 
1008
        traster = (textures ? textures->raster : 0);
 
1009
        ty = y + phase_y;
 
1010
        for (; line_count-- > 0; cdrow += draster, mdrow += draster, ydrow += draster, kdrow += draster, srow += sraster, ++ty) {
 
1011
            int sx = sourcex;
 
1012
            int dx = x;
 
1013
            int w = width;
 
1014
            const byte *trow = textures->data + (ty % textures->rep_height) * traster;
 
1015
            int xoff = x_offset(phase_x, ty, textures);
 
1016
            int nw;
 
1017
            int tx = (dx + xoff) % textures->rep_width;
 
1018
 
 
1019
            /* Loop over (horizontal) copies of the tile. */
 
1020
            for (; w > 0; sx += nw, dx += nw, w -= nw, tx = 0) {
 
1021
                /* sptr and tptr point to bytes of cmykcmyk. Need to convert
 
1022
                 * these to planar format. */
 
1023
                int dbit = dx & 7;
 
1024
                int tbit = tx & 1;
 
1025
                int tskew = tbit - dbit; /* -7 >= tskew >= 1 */
 
1026
                int left = (nw = min(w, textures->size.x - tx))-8+dbit;
 
1027
                int sbit = sx & 1;
 
1028
                int sskew = sbit - dbit; /* -7 >= sskew >= 1 */
 
1029
                byte lmask = 0xff >> dbit;
 
1030
                byte rmask = 0xff << (~(dbit + nw - 1) & 7);
 
1031
                byte *cdptr = cdrow + (dx>>3);
 
1032
                byte *mdptr = mdrow + (dx>>3);
 
1033
                byte *ydptr = ydrow + (dx>>3);
 
1034
                byte *kdptr = kdrow + (dx>>3);
 
1035
                const byte *tptr = trow;
 
1036
                const rop_proc proc = rop_proc_table[rop];
 
1037
                const byte *sptr = srow;
 
1038
                sptr += (sskew>>1); /* Backtrack sptr if required. */
 
1039
                sptr += (sx>>1);
 
1040
                tptr += (tskew>>1); /* Backtrack tptr if required. */
 
1041
                tptr += (tx>>1);
 
1042
                if (left < 0)
 
1043
                    lmask &= rmask;
 
1044
                {
 
1045
                    /* Left hand bytes */
 
1046
                    byte kdbyte = *kdptr;
 
1047
                    byte cdbyte = *cdptr;
 
1048
                    byte mdbyte = *mdptr;
 
1049
                    byte ydbyte = *ydptr;
 
1050
                    byte cresult, mresult, yresult, kresult;
 
1051
                    bits32 scol = 0, tcol = 0;
 
1052
                    if ((sskew & 1) == 0) {
 
1053
                        if (sskew >= 0)
 
1054
                            scol = expand_4to1[sptr[0]]<<6;
 
1055
                        if ((sskew >= -2) && (left > -6))
 
1056
                            scol |= expand_4to1[sptr[1]]<<4;
 
1057
                        if ((sskew >= -4) && (left > -4))
 
1058
                            scol |= expand_4to1[sptr[2]]<<2;
 
1059
                        if (left > -2)
 
1060
                            scol |= expand_4to1[sptr[3]];
 
1061
                    } else {
 
1062
                        if (sskew >= 0)
 
1063
                            scol = expand_4to1[sptr[0] & 0x0f]<<7;
 
1064
                        if ((sskew >= -2) && (left > -7))
 
1065
                            scol |= expand_4to1[sptr[1]]<<5;
 
1066
                        if ((sskew >= -4) && (left > -5))
 
1067
                            scol |= expand_4to1[sptr[2]]<<3;
 
1068
                        if ((sskew >= -6) && (left > -3))
 
1069
                            scol |= expand_4to1[sptr[3]]<<1;
 
1070
                        if (left > -1)
 
1071
                            scol |= expand_4to1[sptr[4] & 0xf0]>>1;
 
1072
                    }
 
1073
                    if ((tskew & 1) == 0) {
 
1074
                        if (tskew >= 0)
 
1075
                            tcol = expand_4to1[tptr[0]]<<6;
 
1076
                        if ((tskew >= -2) && (left > -6))
 
1077
                            tcol |= expand_4to1[tptr[1]]<<4;
 
1078
                        if ((tskew >= -4) && (left > -4))
 
1079
                            tcol |= expand_4to1[tptr[2]]<<2;
 
1080
                        if (left > -2)
 
1081
                            tcol |= expand_4to1[tptr[3]];
 
1082
                    } else {
 
1083
                        if (tskew >= 0)
 
1084
                            tcol = expand_4to1[tptr[0] & 0x0f]<<7;
 
1085
                        if ((tskew >= -2) && (left > -7))
 
1086
                            tcol |= expand_4to1[tptr[1]]<<5;
 
1087
                        if ((tskew >= -4) && (left > -5))
 
1088
                            tcol |= expand_4to1[tptr[2]]<<3;
 
1089
                        if ((tskew >= -6) && (left > -3))
 
1090
                            tcol |= expand_4to1[tptr[3]]<<1;
 
1091
                        if (left > -1)
 
1092
                            tcol |= expand_4to1[tptr[4] & 0xf0]>>1;
 
1093
                    }
 
1094
                    cresult = (*proc)(cdbyte | kdbyte,scol|(scol>>24),tcol|(tcol>>24));
 
1095
                    mresult = (*proc)(mdbyte | kdbyte,scol|(scol>>16),tcol|(tcol>>16));
 
1096
                    yresult = (*proc)(ydbyte | kdbyte,scol|(scol>> 8),tcol|(tcol>> 8));
 
1097
                    kresult = cresult & mresult & yresult;
 
1098
                    cresult &= ~kresult;
 
1099
                    mresult &= ~kresult;
 
1100
                    yresult &= ~kresult;
 
1101
                    *cdptr++ = (cresult & lmask) | (cdbyte & ~lmask);
 
1102
                    *mdptr++ = (mresult & lmask) | (mdbyte & ~lmask);
 
1103
                    *ydptr++ = (yresult & lmask) | (ydbyte & ~lmask);
 
1104
                    *kdptr++ = (kresult & lmask) | (kdbyte & ~lmask);
 
1105
                }
 
1106
                if (left <= 0) /* if (width <= 8) we're done */
 
1107
                    continue;
 
1108
                sptr += 4;
 
1109
                tptr += 4;
 
1110
                left -= 8; /* left = bits to go - 8 */
 
1111
                while (left > 0)
 
1112
                {
 
1113
                    byte kdbyte = *kdptr;
 
1114
                    byte cdbyte = *cdptr | kdbyte;
 
1115
                    byte mdbyte = *mdptr | kdbyte;
 
1116
                    byte ydbyte = *ydptr | kdbyte;
 
1117
                    byte cresult, mresult, yresult, kresult;
 
1118
                    bits32 scol, tcol;
 
1119
                    if ((sskew & 1) == 0) {
 
1120
                        scol  = expand_4to1[sptr[0]]<<6;
 
1121
                        scol |= expand_4to1[sptr[1]]<<4;
 
1122
                        scol |= expand_4to1[sptr[2]]<<2;
 
1123
                        scol |= expand_4to1[sptr[3]];
 
1124
                    } else {
 
1125
                        scol  = expand_4to1[sptr[0] & 0x0f]<<7;
 
1126
                        scol |= expand_4to1[sptr[1]]<<5;
 
1127
                        scol |= expand_4to1[sptr[2]]<<3;
 
1128
                        scol |= expand_4to1[sptr[3]]<<1;
 
1129
                        scol |= expand_4to1[sptr[4] & 0xf0]>>1;
 
1130
                    }
 
1131
                    if ((tskew & 1) == 0) {
 
1132
                        tcol  = expand_4to1[tptr[0]]<<6;
 
1133
                        tcol |= expand_4to1[tptr[1]]<<4;
 
1134
                        tcol |= expand_4to1[tptr[2]]<<2;
 
1135
                        tcol |= expand_4to1[tptr[3]];
 
1136
                    } else {
 
1137
                        tcol  = expand_4to1[tptr[0] & 0x0f]<<7;
 
1138
                        tcol |= expand_4to1[tptr[1]]<<5;
 
1139
                        tcol |= expand_4to1[tptr[2]]<<3;
 
1140
                        tcol |= expand_4to1[tptr[3]]<<1;
 
1141
                        tcol |= expand_4to1[tptr[4] & 0xf0]>>1;
 
1142
                    }
 
1143
                    cresult = (*proc)(cdbyte | kdbyte,scol|(scol>>24),tcol|(tcol>>24));
 
1144
                    mresult = (*proc)(mdbyte | kdbyte,scol|(scol>>16),tcol|(tcol>>16));
 
1145
                    yresult = (*proc)(ydbyte | kdbyte,scol|(scol>> 8),tcol|(tcol>> 8));
 
1146
                    kresult = cresult & mresult & yresult;
 
1147
                    cresult &= ~kresult;
 
1148
                    mresult &= ~kresult;
 
1149
                    yresult &= ~kresult;
 
1150
                    *cdptr++ = cresult & ~kresult;
 
1151
                    *mdptr++ = mresult & ~kresult;
 
1152
                    *ydptr++ = yresult & ~kresult;
 
1153
                    *kdptr++ = kresult;
 
1154
                    sptr += 4;
 
1155
                    tptr += 4;
 
1156
                    left -= 8;
 
1157
                }
 
1158
                {
 
1159
                    byte kdbyte = *kdptr;
 
1160
                    byte cdbyte = *cdptr;
 
1161
                    byte mdbyte = *mdptr;
 
1162
                    byte ydbyte = *ydptr;
 
1163
                    byte cresult, mresult, yresult, kresult;
 
1164
                    bits32 scol, tcol;
 
1165
                    if ((sskew & 1) == 0) {
 
1166
                        scol = expand_4to1[sptr[0]]<<6;
 
1167
                        if (left > -6)
 
1168
                            scol |= expand_4to1[sptr[1]]<<4;
 
1169
                        if (left > -4)
 
1170
                            scol |= expand_4to1[sptr[2]]<<2;
 
1171
                        if (left > -2)
 
1172
                            scol |= expand_4to1[sptr[3]];
 
1173
                    } else {
 
1174
                        scol = expand_4to1[sptr[0] & 0x0f]<<7;
 
1175
                        if (left > -7)
 
1176
                            scol |= expand_4to1[sptr[1]]<<5;
 
1177
                        if (left > -5)
 
1178
                            scol |= expand_4to1[sptr[2]]<<3;
 
1179
                        if (left > -3)
 
1180
                            scol |= expand_4to1[sptr[3]]<<1;
 
1181
                        if (left > -1)
 
1182
                            scol |= expand_4to1[sptr[4] & 0xf0]>>1;
 
1183
                    }
 
1184
                    if ((tskew & 1) == 0) {
 
1185
                        tcol = expand_4to1[tptr[0]]<<6;
 
1186
                        if (left > -6)
 
1187
                            tcol |= expand_4to1[tptr[1]]<<4;
 
1188
                        if (left > -4)
 
1189
                            tcol |= expand_4to1[tptr[2]]<<2;
 
1190
                        if (left > -2)
 
1191
                            tcol |= expand_4to1[tptr[3]];
 
1192
                    } else {
 
1193
                        tcol = expand_4to1[tptr[0] & 0x0f]<<7;
 
1194
                        if (left > -7)
 
1195
                            tcol |= expand_4to1[tptr[1]]<<5;
 
1196
                        if (left > -5)
 
1197
                            tcol |= expand_4to1[tptr[2]]<<3;
 
1198
                        if (left > -3)
 
1199
                            tcol |= expand_4to1[tptr[3]]<<1;
 
1200
                        if (left > -1)
 
1201
                            tcol |= expand_4to1[tptr[4] & 0xf0]>>1;
 
1202
                    }
 
1203
                    cresult = (*proc)(cdbyte | kdbyte,scol|(scol>>24),tcol|(tcol>>24));
 
1204
                    mresult = (*proc)(mdbyte | kdbyte,scol|(scol>>16),tcol|(tcol>>16));
 
1205
                    yresult = (*proc)(ydbyte | kdbyte,scol|(scol>> 8),tcol|(tcol>> 8));
 
1206
                    kresult = cresult & mresult & yresult;
 
1207
                    cresult &= ~kresult;
 
1208
                    mresult &= ~kresult;
 
1209
                    yresult &= ~kresult;
 
1210
                    *cdptr++ = (cresult & rmask) | (cdbyte & ~rmask);
 
1211
                    *mdptr++ = (mresult & rmask) | (mdbyte & ~rmask);
 
1212
                    *ydptr++ = (yresult & rmask) | (ydbyte & ~rmask);
 
1213
                    *kdptr++ = (kresult & rmask) | (kdbyte & ~rmask);
 
1214
                }
 
1215
            }
 
1216
        }
 
1217
        return 0;
 
1218
    }
 
1219
    /* Texture constant (or unimportant) cases */
 
1220
    dbit = x & 7;
 
1221
    cdrow = scan_line_base(mdev, y) + (x>>3);
 
1222
    mdrow = cdrow + mdev->height * draster;
 
1223
    ydrow = mdrow + mdev->height * draster;
 
1224
    kdrow = ydrow + mdev->height * draster;
 
1225
    lmask = 0xff >> dbit;
 
1226
    width += dbit;
 
1227
    rmask = 0xff << (~(width - 1) & 7);
 
1228
    if (width < 8)
 
1229
        lmask &= rmask;
 
1230
    if (scolors == NULL) {
 
1231
        /* sptr points to bytes of cmykcmyk. Need to convert these to
 
1232
         * planar format. */
 
1233
        const rop_proc proc = rop_proc_table[rop];
 
1234
        int sbit = sourcex & 1;
 
1235
        int sskew = sbit - dbit; /* -7 >= sskew >= 1 */
 
1236
        srow += (sskew>>1); /* Backtrack srow if required. */
 
1237
        srow += (sourcex>>1);
 
1238
        for (; line_count-- > 0; cdrow += draster, mdrow += draster, ydrow += draster, kdrow += draster, srow += sraster) {
 
1239
            byte *cdptr = cdrow;
 
1240
            byte *mdptr = mdrow;
 
1241
            byte *ydptr = ydrow;
 
1242
            byte *kdptr = kdrow;
 
1243
            const byte *sptr = srow;
 
1244
            int left = width-8;
 
1245
            {
 
1246
                /* Left hand bytes */
 
1247
                byte kdbyte = *kdptr;
 
1248
                byte cdbyte = *cdptr;
 
1249
                byte mdbyte = *mdptr;
 
1250
                byte ydbyte = *ydptr;
 
1251
                byte cresult, mresult, yresult, kresult;
 
1252
                bits32 scol = 0;
 
1253
                if ((sskew & 1) == 0) {
 
1254
                    if (sskew >= 0)
 
1255
                        scol = expand_4to1[sptr[0]]<<6;
 
1256
                    if ((sskew >= -2) && (left > -6))
 
1257
                        scol |= expand_4to1[sptr[1]]<<4;
 
1258
                    if ((sskew >= -4) && (left > -4))
 
1259
                        scol |= expand_4to1[sptr[2]]<<2;
 
1260
                    if (left > -2)
 
1261
                        scol |= expand_4to1[sptr[3]];
 
1262
                } else {
 
1263
                    if (sskew >= 0)
 
1264
                        scol = expand_4to1[sptr[0] & 0x0f]<<7;
 
1265
                    if ((sskew >= -2) && (left > -7))
 
1266
                        scol |= expand_4to1[sptr[1]]<<5;
 
1267
                    if ((sskew >= -4) && (left > -5))
 
1268
                        scol |= expand_4to1[sptr[2]]<<3;
 
1269
                    if ((sskew >= -6) && (left > -3))
 
1270
                        scol |= expand_4to1[sptr[3]]<<1;
 
1271
                    if (left > -1)
 
1272
                        scol |= expand_4to1[sptr[4] & 0xf0]>>1;
 
1273
                }
 
1274
                cresult = (*proc)(cdbyte | kdbyte,scol|(scol>>24),ctcolor);
 
1275
                mresult = (*proc)(mdbyte | kdbyte,scol|(scol>>16),mtcolor);
 
1276
                yresult = (*proc)(ydbyte | kdbyte,scol|(scol>> 8),ytcolor);
 
1277
                kresult = cresult & mresult & yresult;
 
1278
                cresult &= ~kresult;
 
1279
                mresult &= ~kresult;
 
1280
                yresult &= ~kresult;
 
1281
                *cdptr++ = (cresult & lmask) | (cdbyte & ~lmask);
 
1282
                *mdptr++ = (mresult & lmask) | (mdbyte & ~lmask);
 
1283
                *ydptr++ = (yresult & lmask) | (ydbyte & ~lmask);
 
1284
                *kdptr++ = (kresult & lmask) | (kdbyte & ~lmask);
 
1285
            }
 
1286
            if (left <= 0) /* if (width <= 8) we're done */
 
1287
                continue;
 
1288
            sptr += 4;
 
1289
            left -= 8; /* left = bits to go - 8 */
 
1290
            while (left > 0)
 
1291
            {
 
1292
                byte kdbyte = *kdptr;
 
1293
                byte cdbyte = *cdptr | kdbyte;
 
1294
                byte mdbyte = *mdptr | kdbyte;
 
1295
                byte ydbyte = *ydptr | kdbyte;
 
1296
                byte cresult, mresult, yresult, kresult;
 
1297
                bits32 scol;
 
1298
                if ((sskew & 1) == 0) {
 
1299
                    scol  = expand_4to1[sptr[0]]<<6;
 
1300
                    scol |= expand_4to1[sptr[1]]<<4;
 
1301
                    scol |= expand_4to1[sptr[2]]<<2;
 
1302
                    scol |= expand_4to1[sptr[3]];
 
1303
                } else {
 
1304
                    scol  = expand_4to1[sptr[0] & 0x0f]<<7;
 
1305
                    scol |= expand_4to1[sptr[1]]<<5;
 
1306
                    scol |= expand_4to1[sptr[2]]<<3;
 
1307
                    scol |= expand_4to1[sptr[3]]<<1;
 
1308
                    scol |= expand_4to1[sptr[4] & 0xf0]>>1;
 
1309
                }
 
1310
                cresult = (*proc)(cdbyte | kdbyte,scol|(scol>>24),ctcolor);
 
1311
                mresult = (*proc)(mdbyte | kdbyte,scol|(scol>>16),mtcolor);
 
1312
                yresult = (*proc)(ydbyte | kdbyte,scol|(scol>> 8),ytcolor);
 
1313
                kresult = cresult & mresult & yresult;
 
1314
                cresult &= ~kresult;
 
1315
                mresult &= ~kresult;
 
1316
                yresult &= ~kresult;
 
1317
                *cdptr++ = cresult & ~kresult;
 
1318
                *mdptr++ = mresult & ~kresult;
 
1319
                *ydptr++ = yresult & ~kresult;
 
1320
                *kdptr++ = kresult;
 
1321
                sptr += 4;
 
1322
                left -= 8;
 
1323
            }
 
1324
            {
 
1325
                byte kdbyte = *kdptr;
 
1326
                byte cdbyte = *cdptr;
 
1327
                byte mdbyte = *mdptr;
 
1328
                byte ydbyte = *ydptr;
 
1329
                byte cresult, mresult, yresult, kresult;
 
1330
                bits32 scol;
 
1331
                if ((sskew & 1) == 0) {
 
1332
                    scol = expand_4to1[sptr[0]]<<6;
 
1333
                    if (left > -6)
 
1334
                        scol |= expand_4to1[sptr[1]]<<4;
 
1335
                    if (left > -4)
 
1336
                        scol |= expand_4to1[sptr[2]]<<2;
 
1337
                    if (left > -2)
 
1338
                        scol |= expand_4to1[sptr[3]];
 
1339
                } else {
 
1340
                    scol = expand_4to1[sptr[0] & 0x0f]<<7;
 
1341
                    if (left > -7)
 
1342
                        scol |= expand_4to1[sptr[1]]<<5;
 
1343
                    if (left > -5)
 
1344
                        scol |= expand_4to1[sptr[2]]<<3;
 
1345
                    if (left > -3)
 
1346
                        scol |= expand_4to1[sptr[3]]<<1;
 
1347
                    if (left > -1)
 
1348
                        scol |= expand_4to1[sptr[4] & 0xf0]>>1;
 
1349
                }
 
1350
                cresult = (*proc)(cdbyte | kdbyte,scol|(scol>>24),ctcolor);
 
1351
                mresult = (*proc)(mdbyte | kdbyte,scol|(scol>>16),mtcolor);
 
1352
                yresult = (*proc)(ydbyte | kdbyte,scol|(scol>> 8),ytcolor);
 
1353
                kresult = cresult & mresult & yresult;
 
1354
                cresult &= ~kresult;
 
1355
                mresult &= ~kresult;
 
1356
                yresult &= ~kresult;
 
1357
                *cdptr++ = (cresult & rmask) | (cdbyte & ~rmask);
 
1358
                *mdptr++ = (mresult & rmask) | (mdbyte & ~rmask);
 
1359
                *ydptr++ = (yresult & rmask) | (ydbyte & ~rmask);
 
1360
                *kdptr++ = (kresult & rmask) | (kdbyte & ~rmask);
 
1361
            }
 
1362
        }
 
1363
    } else if (constant_s) {
 
1364
        const rop_proc proc = rop_proc_table[rop];
 
1365
        for (; line_count-- > 0; cdrow += draster, mdrow += draster, ydrow += draster, kdrow += draster) {
 
1366
            byte *cdptr = cdrow;
 
1367
            byte *mdptr = mdrow;
 
1368
            byte *ydptr = ydrow;
 
1369
            byte *kdptr = kdrow;
 
1370
            int left = width-8;
 
1371
            {
 
1372
                /* Left hand bytes */
 
1373
                byte kdbyte = *kdptr;
 
1374
                byte cdbyte = *cdptr;
 
1375
                byte mdbyte = *mdptr;
 
1376
                byte ydbyte = *ydptr;
 
1377
                byte cresult = (*proc)(cdbyte | kdbyte,cscolor,ctcolor);
 
1378
                byte mresult = (*proc)(mdbyte | kdbyte,mscolor,mtcolor);
 
1379
                byte yresult = (*proc)(ydbyte | kdbyte,yscolor,ytcolor);
 
1380
                byte kresult = cresult & mresult & yresult;
 
1381
                cresult &= ~kresult;
 
1382
                mresult &= ~kresult;
 
1383
                yresult &= ~kresult;
 
1384
                *cdptr++ = (cresult & lmask) | (cdbyte & ~lmask);
 
1385
                *mdptr++ = (mresult & lmask) | (mdbyte & ~lmask);
 
1386
                *ydptr++ = (yresult & lmask) | (ydbyte & ~lmask);
 
1387
                *kdptr++ = (kresult & lmask) | (kdbyte & ~lmask);
 
1388
            }
 
1389
            if (left <= 0) /* if (width <= 8) we're done */
 
1390
                continue;
 
1391
            left -= 8; /* left = bits to go - 8 */
 
1392
            while (left > 0)
 
1393
            {
 
1394
                byte kdbyte = *kdptr;
 
1395
                byte cdbyte = *cdptr | kdbyte;
 
1396
                byte mdbyte = *mdptr | kdbyte;
 
1397
                byte ydbyte = *ydptr | kdbyte;
 
1398
                byte cresult = (*proc)(cdbyte,cscolor,ctcolor);
 
1399
                byte mresult = (*proc)(mdbyte,mscolor,mtcolor);
 
1400
                byte yresult = (*proc)(ydbyte,yscolor,ytcolor);
 
1401
                byte kresult = cresult & mresult & yresult;
 
1402
                cresult &= ~kresult;
 
1403
                mresult &= ~kresult;
 
1404
                yresult &= ~kresult;
 
1405
                *cdptr++ = cresult & ~kresult;
 
1406
                *mdptr++ = mresult & ~kresult;
 
1407
                *ydptr++ = yresult & ~kresult;
 
1408
                *kdptr++ = kresult;
 
1409
                left -= 8;
 
1410
            }
 
1411
            {
 
1412
                byte kdbyte = *kdptr;
 
1413
                byte cdbyte = *cdptr;
 
1414
                byte mdbyte = *mdptr;
 
1415
                byte ydbyte = *ydptr;
 
1416
                byte cresult = (*proc)(cdbyte | kdbyte,cscolor,ctcolor);
 
1417
                byte mresult = (*proc)(mdbyte | kdbyte,mscolor,mtcolor);
 
1418
                byte yresult = (*proc)(ydbyte | kdbyte,yscolor,ytcolor);
 
1419
                byte kresult = cresult & mresult & yresult;
 
1420
                cresult &= ~kresult;
 
1421
                mresult &= ~kresult;
 
1422
                yresult &= ~kresult;
 
1423
                *cdptr++ = (cresult & rmask) | (cdbyte & ~rmask);
 
1424
                *mdptr++ = (mresult & rmask) | (mdbyte & ~rmask);
 
1425
                *ydptr++ = (yresult & rmask) | (ydbyte & ~rmask);
 
1426
                *kdptr++ = (kresult & rmask) | (kdbyte & ~rmask);
 
1427
            }
 
1428
        }
 
1429
    } else {
 
1430
        /* Constant T, bitmap S */
 
1431
        int sbit = sourcex & 7;
 
1432
        int sskew = sbit - dbit;
 
1433
        if (sskew < 0)
 
1434
            --srow, sskew += 8;
 
1435
        srow += (sourcex>>3);
 
1436
        for (; line_count-- > 0; cdrow += draster, mdrow += draster, ydrow += draster, kdrow += draster, srow += sraster) {
 
1437
            const byte *sptr = srow;
 
1438
            byte *cdptr = cdrow;
 
1439
            byte *mdptr = mdrow;
 
1440
            byte *ydptr = ydrow;
 
1441
            byte *kdptr = kdrow;
 
1442
            int left = width-8;
 
1443
            {
 
1444
                /* Left hand byte (maybe the only one) */
 
1445
                byte kdbyte = *kdptr;
 
1446
                byte cdbyte = *cdptr;
 
1447
                byte mdbyte = *mdptr;
 
1448
                byte ydbyte = *ydptr;
 
1449
#define fetch1(ptr, skew)\
 
1450
  (skew ? (ptr[0] << skew) + (ptr[1] >> (8 - skew)) : *ptr)
 
1451
                byte sbyte = fetch1(sptr, sskew);
 
1452
                byte cresult = (*cproc)(cdbyte|kdbyte,sbyte,ctcolor);
 
1453
                byte mresult = (*mproc)(mdbyte|kdbyte,sbyte,mtcolor);
 
1454
                byte yresult = (*yproc)(ydbyte|kdbyte,sbyte,ytcolor);
 
1455
                byte kresult = cresult & mresult & yresult;
 
1456
                cresult &= ~kresult;
 
1457
                mresult &= ~kresult;
 
1458
                yresult &= ~kresult;
 
1459
                *cdptr++ = (cresult & lmask) | (cdbyte & ~lmask);
 
1460
                *mdptr++ = (mresult & lmask) | (mdbyte & ~lmask);
 
1461
                *ydptr++ = (yresult & lmask) | (ydbyte & ~lmask);
 
1462
                *kdptr++ = (kresult & lmask) | (kdbyte & ~lmask);
 
1463
                sptr++;
 
1464
                left -= 8;
 
1465
            }
 
1466
            while (left > 0) {
 
1467
                /* Bytes where all 8 bits of S are needed */
 
1468
                byte kdbyte = *kdptr;
 
1469
                byte cdbyte = *cdptr | kdbyte;
 
1470
                byte mdbyte = *mdptr | kdbyte;
 
1471
                byte ydbyte = *ydptr | kdbyte;
 
1472
                byte sbyte = fetch1(sptr, sskew);
 
1473
                byte cresult = (*cproc)(cdbyte,sbyte,ctcolor);
 
1474
                byte mresult = (*mproc)(mdbyte,sbyte,mtcolor);
 
1475
                byte yresult = (*yproc)(ydbyte,sbyte,ytcolor);
 
1476
                byte kresult = cresult & mresult & yresult;
 
1477
                *cdptr++ = cresult & ~kresult;
 
1478
                *mdptr++ = mresult & ~kresult;
 
1479
                *ydptr++ = yresult & ~kresult;
 
1480
                *kdptr++ = kresult;
 
1481
                sptr++;
 
1482
                left -= 8;
 
1483
            }
 
1484
            /* Final byte */
 
1485
            if (left > -8) {
 
1486
                byte kdbyte = *kdptr;
 
1487
                byte cdbyte = *cdptr;
 
1488
                byte mdbyte = *mdptr;
 
1489
                byte ydbyte = *ydptr;
 
1490
                byte sbyte = fetch1(sptr, sskew);
 
1491
#undef fetch1
 
1492
                byte cresult = (*cproc)(cdbyte | kdbyte,sbyte,ctcolor);
 
1493
                byte mresult = (*mproc)(mdbyte | kdbyte,sbyte,mtcolor);
 
1494
                byte yresult = (*yproc)(ydbyte | kdbyte,sbyte,ytcolor);
 
1495
                byte kresult = cresult & mresult & yresult;
 
1496
                cresult &= ~kresult;
 
1497
                mresult &= ~kresult;
 
1498
                yresult &= ~kresult;
 
1499
                *cdptr++ = (cresult & rmask) | (cdbyte & ~rmask);
 
1500
                *mdptr++ = (mresult & rmask) | (mdbyte & ~rmask);
 
1501
                *ydptr++ = (yresult & rmask) | (ydbyte & ~rmask);
 
1502
                *kdptr++ = (kresult & rmask) | (kdbyte & ~rmask);
 
1503
            }
 
1504
        }
 
1505
    }
 
1506
    return 0;
 
1507
}
 
1508
 
 
1509
static int
 
1510
plane_strip_copy_rop(gx_device_memory * mdev,
 
1511
                     const byte * sdata, int sourcex, uint sraster,
 
1512
                     gx_bitmap_id id, const gx_color_index * scolors,
 
1513
                     const gx_strip_bitmap * textures,
 
1514
                     const gx_color_index * tcolors,
 
1515
                     int x, int y, int width, int height,
 
1516
                     int phase_x, int phase_y,
 
1517
                     gs_logical_operation_t lop, int plane)
 
1518
{
666
1519
    mem_save_params_t save;
667
 
    int plane, code;
 
1520
    int code;
668
1521
    const gx_device_memory *mdproto;
669
1522
 
670
 
    if ((lop & lop_planar) == 0) {
671
 
        mdproto = gdev_mem_device_for_bits(mdev->color_info.depth);
672
 
        return dev_proc(mdproto, strip_copy_rop)(dev, sdata, sourcex, sraster,
673
 
                                                 id, scolors, textures, tcolors,
674
 
                                                 x, y, width, height,
675
 
                                                 phase_x, phase_y, lop);
676
 
    }
677
 
    /* Extract the plane, and sanitise the lop */
678
 
    plane = lop>>lop_planar_shift;
679
 
    lop &= ~((plane<<lop_planar_shift) | lop_planar);
680
 
    if ((plane < 0) || (plane >= mdev->num_planes))
681
 
        return gs_error_rangecheck;
682
1523
    MEM_SAVE_PARAMS(mdev, save);
683
1524
    mdev->line_ptrs += mdev->height * plane;
684
1525
    mdproto = gdev_mem_device_for_bits(mdev->planes[plane].depth);
685
 
    /* strip_copy_rop might end up calling get_bits_rectangle, so ensure we
686
 
     * have the right one in there. */
 
1526
    /* strip_copy_rop might end up calling get_bits_rectangle or fill_rectangle,
 
1527
     * so ensure we have the right ones in there. */
687
1528
    set_dev_proc(mdev, get_bits_rectangle, dev_proc(mdproto, get_bits_rectangle));
688
 
    code = dev_proc(mdproto, strip_copy_rop)(dev, sdata, sourcex, sraster,
 
1529
    set_dev_proc(mdev, fill_rectangle, dev_proc(mdproto, fill_rectangle));
 
1530
    code = dev_proc(mdproto, strip_copy_rop)((gx_device *)mdev, sdata, sourcex, sraster,
689
1531
                                             id, scolors, textures, tcolors,
690
1532
                                             x, y, width, height,
691
1533
                                             phase_x, phase_y, lop);
692
1534
    set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle);
 
1535
    set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle);
 
1536
    /* The following effectively does: mdev->line_ptrs -= mdev->height * plane; */
693
1537
    MEM_RESTORE_PARAMS(mdev, save);
694
1538
    return code;
695
1539
}
701
1545
 */
702
1546
static int
703
1547
planar_to_chunky(gx_device_memory *mdev, int x, int y, int w, int h,
704
 
                 int offset, uint draster, byte *dest)
 
1548
                 int offset, uint draster, byte *dest, byte **line_ptrs,
 
1549
                 int plane_height)
705
1550
{
706
1551
    int num_planes = mdev->num_planes;
707
1552
    sample_load_declare(sptr[GX_DEVICE_COLOR_MAX_COMPONENTS],
727
1572
            }
728
1573
    }
729
1574
    for (iy = y; iy < y + h; ++iy) {
730
 
        byte **line_ptr = mdev->line_ptrs + iy;
 
1575
        byte **line_ptr = line_ptrs + iy;
731
1576
 
732
 
        for (pi = 0; pi < num_planes; ++pi, line_ptr += mdev->height) {
 
1577
        for (pi = 0; pi < num_planes; ++pi, line_ptr += plane_height) {
733
1578
            int plane_depth = mdev->planes[pi].depth;
734
1579
            int xbit = x * plane_depth;
735
1580
 
787
1632
    return 0;
788
1633
}
789
1634
 
 
1635
static byte cmykrop[256] =
 
1636
{
 
1637
    255,127,191,63,223,95,159,31,239,111,175,47,207,79,143,15,
 
1638
    247,119,183,55,215,87,151,23,231,103,167,39,199,71,135,7,
 
1639
    251,123,187,59,219,91,155,27,235,107,171,43,203,75,139,11,
 
1640
    243,115,179,51,211,83,147,19,227,99,163,35,195,67,131,3,
 
1641
    253,125,189,61,221,93,157,29,237,109,173,45,205,77,141,13,
 
1642
    245,117,181,53,213,85,149,21,229,101,165,37,197,69,133,5,
 
1643
    249,121,185,57,217,89,153,25,233,105,169,41,201,73,137,9,
 
1644
    241,113,177,49,209,81,145,17,225,97,161,33,193,65,129,1,
 
1645
    254,126,190,62,222,94,158,30,238,110,174,46,206,78,142,14,
 
1646
    246,118,182,54,214,86,150,22,230,102,166,38,198,70,134,6,
 
1647
    250,122,186,58,218,90,154,26,234,106,170,42,202,74,138,10,
 
1648
    242,114,178,50,210,82,146,18,226,98,162,34,194,66,130,2,
 
1649
    252,124,188,60,220,92,156,28,236,108,172,44,204,76,140,12,
 
1650
    244,116,180,52,212,84,148,20,228,100,164,36,196,68,132,4,
 
1651
    248,120,184,56,216,88,152,24,232,104,168,40,200,72,136,8,
 
1652
    240,112,176,48,208,80,144,16,224,96,160,32,192,64,128,0
 
1653
};
 
1654
 
 
1655
static int
 
1656
mem_planar_strip_copy_rop(gx_device * dev,
 
1657
                          const byte * sdata, int sourcex, uint sraster,
 
1658
                          gx_bitmap_id id, const gx_color_index * scolors,
 
1659
                          const gx_strip_bitmap * textures,
 
1660
                          const gx_color_index * tcolors,
 
1661
                          int x, int y, int width, int height,
 
1662
                          int phase_x, int phase_y,
 
1663
                          gs_logical_operation_t lop)
 
1664
{
 
1665
    return mem_planar_strip_copy_rop2(dev, sdata, sourcex, sraster,
 
1666
                                      id, scolors, textures, tcolors,
 
1667
                                      x, y, width, height,
 
1668
                                      phase_x, phase_y, lop, 0);
 
1669
}
 
1670
 
 
1671
static int
 
1672
mem_planar_strip_copy_rop2(gx_device * dev,
 
1673
                           const byte * sdata, int sourcex, uint sraster,
 
1674
                           gx_bitmap_id id, const gx_color_index * scolors,
 
1675
                           const gx_strip_bitmap * textures,
 
1676
                           const gx_color_index * tcolors,
 
1677
                           int x, int y, int width, int height,
 
1678
                           int phase_x, int phase_y,
 
1679
                           gs_logical_operation_t lop,
 
1680
                           uint planar_height)
 
1681
{
 
1682
    gx_device_memory * const mdev = (gx_device_memory *)dev;
 
1683
    int code;
 
1684
 
 
1685
    if (planar_height != 0) {
 
1686
        /* S is in planar format; expand it to a temporary buffer, then
 
1687
         * call ourselves back with a modified rop to use it, then free
 
1688
         * the temporary buffer, and return. */
 
1689
        /* Make a temporary buffer that contains both the raster and the line
 
1690
         * pointers for the buffer. For now, for the sake of sanity, we
 
1691
         * convert whole lines of s, but only as many lines as we have to. */
 
1692
        /* We assume that scolors == NULL here */
 
1693
        int i, j;
 
1694
        uint chunky_sraster;
 
1695
        uint nbytes;
 
1696
        byte **line_ptrs;
 
1697
        byte *sbuf, *buf;
 
1698
 
 
1699
        chunky_sraster = sraster * mdev->num_planes;
 
1700
        nbytes = height * chunky_sraster;
 
1701
        buf = gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(buf)");
 
1702
        if (buf == NULL) {
 
1703
            return gs_note_error(gs_error_VMerror);
 
1704
        }
 
1705
        nbytes = sizeof(byte *) * mdev->num_planes * height;
 
1706
        line_ptrs = (byte **)gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(line_ptrs)");
 
1707
        if (line_ptrs == NULL) {
 
1708
            gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)");
 
1709
            return gs_note_error(gs_error_VMerror);
 
1710
        }
 
1711
        for (j = 0; j < mdev->num_planes; j++) {
 
1712
            sbuf = sdata + j * sraster;
 
1713
            for (i = height; i > 0; i--) {
 
1714
                *line_ptrs++ = sbuf;
 
1715
                sbuf += sraster;
 
1716
            }
 
1717
        }
 
1718
        line_ptrs -= height * mdev->num_planes;
 
1719
        planar_to_chunky(mdev, sourcex, 0, width, height,
 
1720
                         0, chunky_sraster, buf, line_ptrs, planar_height);
 
1721
        gs_free_object(mdev->memory, line_ptrs, "mem_planar_strip_copy_rop(line_ptrs)");
 
1722
        code = mem_planar_strip_copy_rop2(dev, buf, 0, chunky_sraster,
 
1723
                                          id, scolors, textures, tcolors,
 
1724
                                          x, y, width, height, phase_x, phase_y,
 
1725
                                          lop, 0);
 
1726
        gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)");
 
1727
        return code;
 
1728
    }
 
1729
 
 
1730
    if (textures && textures->num_planes > 1) {
 
1731
        /* T is in planar format; expand it to a temporary buffer, then
 
1732
         * call ourselves back with a modified rop to use it, then free
 
1733
         * the temporary buffer, and return. */
 
1734
        /* Make a temporary buffer that contains both the raster and the line
 
1735
         * pointers for the buffer. For now, for the sake of sanity, we
 
1736
         * convert whole lines of t, but only as many lines as we have to
 
1737
         * (unless it loops). */
 
1738
        /* We assume that tcolors == NULL here */
 
1739
        int ty, i;
 
1740
        uint chunky_t_raster;
 
1741
        uint chunky_t_height;
 
1742
        uint nbytes;
 
1743
        byte **line_ptrs;
 
1744
        byte *tbuf, *buf;
 
1745
        gx_strip_bitmap newtex;
 
1746
 
 
1747
        ty = (y + phase_y) % textures->rep_height;
 
1748
        if (ty < 0)
 
1749
            ty += textures->rep_height;
 
1750
        chunky_t_raster = bitmap_raster(textures->rep_width * mdev->color_info.depth);
 
1751
        if (ty + height <= textures->rep_height) {
 
1752
            chunky_t_height = height;
 
1753
            phase_y = -y;
 
1754
        } else {
 
1755
            ty = 0;
 
1756
            chunky_t_height = textures->rep_height;
 
1757
        }
 
1758
        nbytes = chunky_t_height * chunky_t_raster;
 
1759
        buf = gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(buf)");
 
1760
        if (buf == NULL) {
 
1761
            return gs_note_error(gs_error_VMerror);
 
1762
        }
 
1763
        nbytes = sizeof(byte *) * mdev->num_planes * textures->rep_height;
 
1764
        line_ptrs = (byte **)gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(line_ptrs)");
 
1765
        if (line_ptrs == NULL) {
 
1766
            gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)");
 
1767
            return gs_note_error(gs_error_VMerror);
 
1768
        }
 
1769
        tbuf = textures->data;
 
1770
        for (i = textures->rep_height * mdev->num_planes; i > 0; i--) {
 
1771
            *line_ptrs++ = tbuf;
 
1772
            tbuf += textures->raster;
 
1773
        }
 
1774
        line_ptrs -= textures->rep_height * mdev->num_planes;
 
1775
        planar_to_chunky(mdev, 0, ty, textures->rep_width, chunky_t_height,
 
1776
                         0, chunky_t_raster, buf, line_ptrs, textures->rep_height);
 
1777
        gs_free_object(mdev->memory, line_ptrs, "mem_planar_strip_copy_rop(line_ptrs)");
 
1778
        newtex = *textures;
 
1779
        newtex.data = buf;
 
1780
        newtex.raster = chunky_t_raster;
 
1781
        newtex.num_planes = 1;
 
1782
        newtex.size.x = textures->rep_width;
 
1783
        newtex.size.y = textures->rep_height;
 
1784
        code = mem_planar_strip_copy_rop2(dev, sdata, sourcex, sraster,
 
1785
                                          id, scolors, &newtex, tcolors,
 
1786
                                          x, y, width, height, phase_x, phase_y,
 
1787
                                          lop, planar_height);
 
1788
        gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)");
 
1789
        return code;
 
1790
    }
 
1791
 
 
1792
    /* Not doing a planar lop. If we carry on down the default path here,
 
1793
     * we'll end up doing a planar_to_chunky; we may be able to sidestep
 
1794
     * that by spotting cases where we can operate directly. */
 
1795
    if (!lop_uses_T(lop) || (tcolors && (tcolors[0] == tcolors[1]))) {
 
1796
        /* No T in use, or constant T. */
 
1797
        if ((!lop_uses_S(lop) || (scolors && (scolors[0] == scolors[1]))) &&
 
1798
            ((mdev->num_planes == 1) || (mdev->num_planes == 3))) {
 
1799
            int plane;
 
1800
            /* No S in use, or constant S. And either greyscale or rgb,
 
1801
             * so we can just do the rop on each plane in turn. */
 
1802
            for (plane=0; plane < mdev->num_planes; plane++)
 
1803
            {
 
1804
                gx_color_index tcolors2[2], scolors2[2];
 
1805
                int shift = mdev->planes[plane].shift;
 
1806
                int mask = (1<<mdev->planes[plane].depth)-1;
 
1807
 
 
1808
                if (tcolors) {
 
1809
                    tcolors2[0] = (tcolors[0] >> shift) & mask;
 
1810
                    tcolors2[1] = (tcolors[1] >> shift) & mask;
 
1811
                }
 
1812
                if (scolors) {
 
1813
                    scolors2[0] = (scolors[0] >> shift) & mask;
 
1814
                    scolors2[1] = (scolors[1] >> shift) & mask;
 
1815
                }
 
1816
                code = plane_strip_copy_rop(mdev, sdata, sourcex, sraster,
 
1817
                                            id, (scolors ? scolors2 : NULL),
 
1818
                                            textures, (tcolors ? tcolors2 : NULL),
 
1819
                                            x, y, width, height,
 
1820
                                            phase_x, phase_y, lop, plane);
 
1821
                if (code < 0)
 
1822
                    return code;
 
1823
            }
 
1824
            return 0;
 
1825
        }
 
1826
        if ((mdev->num_planes == 4) && (mdev->plane_depth == 1) &&
 
1827
            ((lop & (lop_S_transparent | lop_T_transparent)) == 0))
 
1828
        {
 
1829
            lop = cmykrop[lop & 0xff] | (lop & ~0xff);
 
1830
            return planar_cmyk4bit_strip_copy_rop(mdev, sdata, sourcex,
 
1831
                                                  sraster, id, scolors,
 
1832
                                                  textures, tcolors,
 
1833
                                                  x, y, width, height,
 
1834
                                                  phase_x, phase_y,
 
1835
                                                  lop);
 
1836
        }
 
1837
    }
 
1838
    if (!tcolors && !scolors &&
 
1839
        (mdev->num_planes == 4) && (mdev->plane_depth == 1) &&
 
1840
        ((lop & (lop_S_transparent | lop_T_transparent)) == 0)) {
 
1841
        lop = cmykrop[lop & 0xff] | (lop & ~0xff);
 
1842
        return planar_cmyk4bit_strip_copy_rop(mdev, sdata, sourcex,
 
1843
                                              sraster, id, scolors,
 
1844
                                              textures, tcolors,
 
1845
                                              x, y, width, height,
 
1846
                                              phase_x, phase_y,
 
1847
                                              lop);
 
1848
    }
 
1849
    /* Fall back to the default implementation (the only one that
 
1850
     * guarantees to properly cope with D being planar). */
 
1851
    return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster,
 
1852
                                      id, scolors, textures, tcolors,
 
1853
                                      x, y, width, height,
 
1854
                                      phase_x, phase_y, lop);
 
1855
}
 
1856
 
790
1857
/* Copy bits back from a planar memory device. */
791
1858
static int
792
1859
mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
906
1973
            (options & GB_RASTER_SPECIFIED ? params->raster :
907
1974
             bitmap_raster((offset + w) * mdev->color_info.depth));
908
1975
 
909
 
        planar_to_chunky(mdev, x, y, w, h, offset, draster, params->data[0]);
 
1976
        planar_to_chunky(mdev, x, y, w, h, offset, draster, params->data[0],
 
1977
                         mdev->line_ptrs, mdev->height);
910
1978
    } else {
911
1979
        /*
912
1980
         * Do the transfer through an intermediate buffer.
960
2028
            ch = min(bh, y + h - cy);
961
2029
            for (cx = x; cx < x + w; cx += cw) {
962
2030
                cw = min(bw, x + w - cx);
963
 
                planar_to_chunky(mdev, cx, cy, cw, ch, 0, br, buf.b);
 
2031
                planar_to_chunky(mdev, cx, cy, cw, ch, 0, br, buf.b,
 
2032
                                 mdev->line_ptrs, mdev->height);
964
2033
                code = gx_get_bits_copy(dev, 0, cw, ch, &dest_params,
965
2034
                                        &copy_params, buf.b, br);
966
2035
                if (code < 0)