470
509
MEM_RESTORE_PARAMS(mdev, save);
514
static bits32 expand_4to1[256] =
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
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)
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)
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;
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) {
609
bh = BUF_BYTES / plane_raster;
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);
617
cw = min(bw, x + w - cx);
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;
629
cmyk |= expand_4to1[*sptr++]<<roll;
647
source_base += sraster;
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;
658
byte b = *sptr++ & 0x0f;
666
cmyk |= expand_4to1[b & 0xf0]>>1;
676
cmyk |= expand_4to1[b]<<roll;
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. */
683
/* Flush the stored bytes */
689
source_base += sraster;
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;
710
MEM_RESTORE_PARAMS(mdev, save);
474
715
/* Copy a color bitmap. */
475
716
/* This is slow and messy. */
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)
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)
909
gs_rop3_t rop = (gs_rop3_t)lop;
910
uint draster = mdev->raster;
912
byte *cdrow, *mdrow, *ydrow, *kdrow;
914
rop_proc cproc, mproc, yproc;
916
int cscolor, mscolor, yscolor, kscolor;
917
int ctcolor, mtcolor, ytcolor, ktcolor;
920
/* Modify the raster operation according to the source palette. */
921
fit_copy(mdev, srow, sourcex, sraster, id, x, y, width, height);
923
/* This function assumes constant (or unused) scolors and tcolors */
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;
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;
939
cproc = rop_proc_table[rop3_know_S_0(rop)];
942
cproc = rop_proc_table[rop3_invert_S(rop)];
945
cproc = rop_proc_table[rop];
948
cproc = rop_proc_table[rop3_know_S_1(rop)];
953
mproc = rop_proc_table[rop3_know_S_0(rop)];
956
mproc = rop_proc_table[rop3_invert_S(rop)];
959
mproc = rop_proc_table[rop];
962
mproc = rop_proc_table[rop3_know_S_1(rop)];
967
yproc = rop_proc_table[rop3_know_S_0(rop)];
970
yproc = rop_proc_table[rop3_invert_S(rop)];
973
yproc = rop_proc_table[rop];
976
yproc = rop_proc_table[rop3_know_S_1(rop)];
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;
989
/* Set up transfer parameters. */
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
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)
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);
1010
for (; line_count-- > 0; cdrow += draster, mdrow += draster, ydrow += draster, kdrow += draster, srow += sraster, ++ty) {
1014
const byte *trow = textures->data + (ty % textures->rep_height) * traster;
1015
int xoff = x_offset(phase_x, ty, textures);
1017
int tx = (dx + xoff) % textures->rep_width;
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. */
1025
int tskew = tbit - dbit; /* -7 >= tskew >= 1 */
1026
int left = (nw = min(w, textures->size.x - tx))-8+dbit;
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. */
1040
tptr += (tskew>>1); /* Backtrack tptr if required. */
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) {
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;
1060
scol |= expand_4to1[sptr[3]];
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;
1071
scol |= expand_4to1[sptr[4] & 0xf0]>>1;
1073
if ((tskew & 1) == 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;
1081
tcol |= expand_4to1[tptr[3]];
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;
1092
tcol |= expand_4to1[tptr[4] & 0xf0]>>1;
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);
1106
if (left <= 0) /* if (width <= 8) we're done */
1110
left -= 8; /* left = bits to go - 8 */
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;
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]];
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;
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]];
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;
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;
1159
byte kdbyte = *kdptr;
1160
byte cdbyte = *cdptr;
1161
byte mdbyte = *mdptr;
1162
byte ydbyte = *ydptr;
1163
byte cresult, mresult, yresult, kresult;
1165
if ((sskew & 1) == 0) {
1166
scol = expand_4to1[sptr[0]]<<6;
1168
scol |= expand_4to1[sptr[1]]<<4;
1170
scol |= expand_4to1[sptr[2]]<<2;
1172
scol |= expand_4to1[sptr[3]];
1174
scol = expand_4to1[sptr[0] & 0x0f]<<7;
1176
scol |= expand_4to1[sptr[1]]<<5;
1178
scol |= expand_4to1[sptr[2]]<<3;
1180
scol |= expand_4to1[sptr[3]]<<1;
1182
scol |= expand_4to1[sptr[4] & 0xf0]>>1;
1184
if ((tskew & 1) == 0) {
1185
tcol = expand_4to1[tptr[0]]<<6;
1187
tcol |= expand_4to1[tptr[1]]<<4;
1189
tcol |= expand_4to1[tptr[2]]<<2;
1191
tcol |= expand_4to1[tptr[3]];
1193
tcol = expand_4to1[tptr[0] & 0x0f]<<7;
1195
tcol |= expand_4to1[tptr[1]]<<5;
1197
tcol |= expand_4to1[tptr[2]]<<3;
1199
tcol |= expand_4to1[tptr[3]]<<1;
1201
tcol |= expand_4to1[tptr[4] & 0xf0]>>1;
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);
1219
/* Texture constant (or unimportant) cases */
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;
1227
rmask = 0xff << (~(width - 1) & 7);
1230
if (scolors == NULL) {
1231
/* sptr points to bytes of cmykcmyk. Need to convert these to
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;
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;
1253
if ((sskew & 1) == 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;
1261
scol |= expand_4to1[sptr[3]];
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;
1272
scol |= expand_4to1[sptr[4] & 0xf0]>>1;
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);
1286
if (left <= 0) /* if (width <= 8) we're done */
1289
left -= 8; /* left = bits to go - 8 */
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;
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]];
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;
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;
1325
byte kdbyte = *kdptr;
1326
byte cdbyte = *cdptr;
1327
byte mdbyte = *mdptr;
1328
byte ydbyte = *ydptr;
1329
byte cresult, mresult, yresult, kresult;
1331
if ((sskew & 1) == 0) {
1332
scol = expand_4to1[sptr[0]]<<6;
1334
scol |= expand_4to1[sptr[1]]<<4;
1336
scol |= expand_4to1[sptr[2]]<<2;
1338
scol |= expand_4to1[sptr[3]];
1340
scol = expand_4to1[sptr[0] & 0x0f]<<7;
1342
scol |= expand_4to1[sptr[1]]<<5;
1344
scol |= expand_4to1[sptr[2]]<<3;
1346
scol |= expand_4to1[sptr[3]]<<1;
1348
scol |= expand_4to1[sptr[4] & 0xf0]>>1;
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);
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;
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);
1389
if (left <= 0) /* if (width <= 8) we're done */
1391
left -= 8; /* left = bits to go - 8 */
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;
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);
1430
/* Constant T, bitmap S */
1431
int sbit = sourcex & 7;
1432
int sskew = sbit - dbit;
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;
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);
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;
1486
byte kdbyte = *kdptr;
1487
byte cdbyte = *cdptr;
1488
byte mdbyte = *mdptr;
1489
byte ydbyte = *ydptr;
1490
byte sbyte = fetch1(sptr, sskew);
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);
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)
666
1519
mem_save_params_t save;
668
1521
const gx_device_memory *mdproto;
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,
675
phase_x, phase_y, lop);
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);
1635
static byte cmykrop[256] =
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
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)
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);
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,
1682
gx_device_memory * const mdev = (gx_device_memory *)dev;
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 */
1694
uint chunky_sraster;
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)");
1703
return gs_note_error(gs_error_VMerror);
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);
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;
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,
1726
gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)");
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 */
1740
uint chunky_t_raster;
1741
uint chunky_t_height;
1745
gx_strip_bitmap newtex;
1747
ty = (y + phase_y) % textures->rep_height;
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;
1756
chunky_t_height = textures->rep_height;
1758
nbytes = chunky_t_height * chunky_t_raster;
1759
buf = gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(buf)");
1761
return gs_note_error(gs_error_VMerror);
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);
1769
tbuf = textures->data;
1770
for (i = textures->rep_height * mdev->num_planes; i > 0; i--) {
1771
*line_ptrs++ = tbuf;
1772
tbuf += textures->raster;
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)");
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)");
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))) {
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++)
1804
gx_color_index tcolors2[2], scolors2[2];
1805
int shift = mdev->planes[plane].shift;
1806
int mask = (1<<mdev->planes[plane].depth)-1;
1809
tcolors2[0] = (tcolors[0] >> shift) & mask;
1810
tcolors2[1] = (tcolors[1] >> shift) & mask;
1813
scolors2[0] = (scolors[0] >> shift) & mask;
1814
scolors2[1] = (scolors[1] >> shift) & mask;
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);
1826
if ((mdev->num_planes == 4) && (mdev->plane_depth == 1) &&
1827
((lop & (lop_S_transparent | lop_T_transparent)) == 0))
1829
lop = cmykrop[lop & 0xff] | (lop & ~0xff);
1830
return planar_cmyk4bit_strip_copy_rop(mdev, sdata, sourcex,
1831
sraster, id, scolors,
1833
x, y, width, height,
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,
1845
x, y, width, height,
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);
790
1857
/* Copy bits back from a planar memory device. */
792
1859
mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,