1/*
2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#if !defined(JAVA2D_NO_MLIB) || defined(MLIB_ADD_SUFF)
27
28#include <vis_proto.h>
29#include "java2d_Mlib.h"
30#include "vis_AlphaMacros.h"
31
32/***************************************************************/
33
34#define RGB2GRAY(r, g, b)      \
35    (((77 * (r)) + (150 * (g)) + (29 * (b)) + 128) >> 8)
36
37/***************************************************************/
38
39#define Gray2Argb(x)   \
40    0xff000000 | (x << 16) | (x << 8) | x
41
42/***************************************************************/
43
44#define LUT(x)         \
45    ((mlib_u8*)LutU8)[4 * (x)]
46
47#define LUT12(x)       \
48    ((mlib_u8*)LutU8)[4 * ((x) & 0xfff)]
49
50/***************************************************************/
51
52void ADD_SUFF(UshortGrayToByteGrayConvert)(BLIT_PARAMS)
53{
54    mlib_s32 dstScan = pDstInfo->scanStride;
55    mlib_s32 srcScan = pSrcInfo->scanStride;
56    mlib_u8  *dst_end;
57    mlib_d64 s0, s1, ss;
58    mlib_s32 i, j;
59
60    if (width <= 8) {
61        for (j = 0; j < height; j++) {
62            mlib_u8 *src = srcBase;
63            mlib_u8 *dst = dstBase;
64
65            for (i = 0; i < width; i++) {
66                dst[i] = src[2*i];
67            }
68
69            PTR_ADD(dstBase, dstScan);
70            PTR_ADD(srcBase, srcScan);
71        }
72        return;
73    }
74
75    if (srcScan == 2*width && dstScan == width) {
76        width *= height;
77        height = 1;
78    }
79
80    for (j = 0; j < height; j++) {
81        mlib_u8 *src = srcBase;
82        mlib_u8 *dst = dstBase;
83        mlib_d64 *sp;
84
85        dst_end = dst + width;
86
87        while (((mlib_s32)dst & 3) && dst < dst_end) {
88            *dst++ = *src;
89            src += 2;
90        }
91
92        if ((mlib_s32)src & 7) {
93            sp = vis_alignaddr(src, 0);
94            s1 = *sp++;
95
96#pragma pipeloop(0)
97            for (; dst <= (dst_end - 4); dst += 4) {
98                s0 = s1;
99                s1 = *sp++;
100                ss = vis_faligndata(s0, s1);
101                ss = vis_fpmerge(vis_read_hi(ss), vis_read_lo(ss));
102                ss = vis_fpmerge(vis_read_hi(ss), vis_read_lo(ss));
103                *(mlib_f32*)dst = vis_read_hi(ss);
104                src += 2*4;
105            }
106        } else {
107#pragma pipeloop(0)
108            for (; dst <= (dst_end - 4); dst += 4) {
109                ss = *(mlib_d64*)src;
110                ss = vis_fpmerge(vis_read_hi(ss), vis_read_lo(ss));
111                ss = vis_fpmerge(vis_read_hi(ss), vis_read_lo(ss));
112                *(mlib_f32*)dst = vis_read_hi(ss);
113                src += 2*4;
114            }
115        }
116
117        while (dst < dst_end) {
118            *dst++ = *src;
119            src += 2;
120        }
121
122        PTR_ADD(dstBase, dstScan);
123        PTR_ADD(srcBase, srcScan);
124    }
125}
126
127/***************************************************************/
128
129void ADD_SUFF(ByteGrayToIntArgbConvert)(BLIT_PARAMS)
130{
131    mlib_s32 dstScan = pDstInfo->scanStride;
132    mlib_s32 srcScan = pSrcInfo->scanStride;
133    mlib_d64 d0, d1, d2, d3;
134    mlib_f32 ff, aa = vis_fones();
135    mlib_s32 i, j, x;
136
137    if (width < 8) {
138        for (j = 0; j < height; j++) {
139            mlib_u8  *src = srcBase;
140            mlib_s32 *dst = dstBase;
141
142            for (i = 0; i < width; i++) {
143                x = src[i];
144                dst[i] = Gray2Argb(x);
145            }
146
147            PTR_ADD(dstBase, dstScan);
148            PTR_ADD(srcBase, srcScan);
149        }
150        return;
151    }
152
153    if (srcScan == width && dstScan == 4*width) {
154        width *= height;
155        height = 1;
156    }
157
158    for (j = 0; j < height; j++) {
159        mlib_u8  *src = srcBase;
160        mlib_s32 *dst = dstBase;
161        mlib_s32 *dst_end;
162
163        dst_end = dst + width;
164
165        while (((mlib_s32)src & 3) && dst < dst_end) {
166            x = *src++;
167            *dst++ = Gray2Argb(x);
168        }
169
170#pragma pipeloop(0)
171        for (; dst <= (dst_end - 4); dst += 4) {
172            ff = *(mlib_f32*)src;
173            d0 = vis_fpmerge(aa, ff);
174            d1 = vis_fpmerge(ff, ff);
175            d2 = vis_fpmerge(vis_read_hi(d0), vis_read_hi(d1));
176            d3 = vis_fpmerge(vis_read_lo(d0), vis_read_lo(d1));
177            ((mlib_f32*)dst)[0] = vis_read_hi(d2);
178            ((mlib_f32*)dst)[1] = vis_read_lo(d2);
179            ((mlib_f32*)dst)[2] = vis_read_hi(d3);
180            ((mlib_f32*)dst)[3] = vis_read_lo(d3);
181            src += 4;
182        }
183
184        while (dst < dst_end) {
185            x = *src++;
186            *dst++ = Gray2Argb(x);
187        }
188
189        PTR_ADD(dstBase, dstScan);
190        PTR_ADD(srcBase, srcScan);
191    }
192}
193
194/***************************************************************/
195
196void ADD_SUFF(ByteGrayToIntArgbScaleConvert)(SCALE_PARAMS)
197{
198    mlib_s32 dstScan = pDstInfo->scanStride;
199    mlib_s32 srcScan = pSrcInfo->scanStride;
200    mlib_d64 d0, d1, d2, d3, dd;
201    mlib_f32 ff, aa = vis_fones();
202    mlib_s32 i, j, x;
203
204    if (width < 16) {
205        for (j = 0; j < height; j++) {
206            mlib_u8  *src = srcBase;
207            mlib_s32 *dst = dstBase;
208            mlib_s32 tmpsxloc = sxloc;
209
210            PTR_ADD(src, (syloc >> shift) * srcScan);
211
212            for (i = 0; i < width; i++) {
213                x = src[tmpsxloc >> shift];
214                tmpsxloc += sxinc;
215                dst[i] = Gray2Argb(x);
216            }
217
218            PTR_ADD(dstBase, dstScan);
219            syloc += syinc;
220        }
221        return;
222    }
223
224    vis_alignaddr(NULL, 7);
225
226    for (j = 0; j < height; j++) {
227        mlib_u8  *src = srcBase;
228        mlib_s32 *dst = dstBase;
229        mlib_s32 *dst_end;
230        mlib_s32 tmpsxloc = sxloc;
231
232        PTR_ADD(src, (syloc >> shift) * srcScan);
233
234        dst_end = dst + width;
235
236#pragma pipeloop(0)
237        for (; dst <= (dst_end - 4); dst += 4) {
238            LOAD_NEXT_U8(dd, src + ((tmpsxloc + 3*sxinc) >> shift));
239            LOAD_NEXT_U8(dd, src + ((tmpsxloc + 2*sxinc) >> shift));
240            LOAD_NEXT_U8(dd, src + ((tmpsxloc +   sxinc) >> shift));
241            LOAD_NEXT_U8(dd, src + ((tmpsxloc          ) >> shift));
242            tmpsxloc += 4*sxinc;
243            ff = vis_read_hi(dd);
244            d0 = vis_fpmerge(aa, ff);
245            d1 = vis_fpmerge(ff, ff);
246            d2 = vis_fpmerge(vis_read_hi(d0), vis_read_hi(d1));
247            d3 = vis_fpmerge(vis_read_lo(d0), vis_read_lo(d1));
248            ((mlib_f32*)dst)[0] = vis_read_hi(d2);
249            ((mlib_f32*)dst)[1] = vis_read_lo(d2);
250            ((mlib_f32*)dst)[2] = vis_read_hi(d3);
251            ((mlib_f32*)dst)[3] = vis_read_lo(d3);
252        }
253
254        while (dst < dst_end) {
255            x = src[tmpsxloc >> shift];
256            tmpsxloc += sxinc;
257            *dst++ = Gray2Argb(x);
258        }
259
260        PTR_ADD(dstBase, dstScan);
261        syloc += syinc;
262    }
263}
264
265/***************************************************************/
266
267#if 1
268
269#ifdef MLIB_ADD_SUFF
270#pragma weak ByteGrayToIntArgbPreConvert_F = ByteGrayToIntArgbConvert_F
271#else
272#pragma weak ByteGrayToIntArgbPreConvert   = ByteGrayToIntArgbConvert
273#endif
274
275#ifdef MLIB_ADD_SUFF
276#pragma weak ByteGrayToIntArgbPreScaleConvert_F =      \
277             ByteGrayToIntArgbScaleConvert_F
278#else
279#pragma weak ByteGrayToIntArgbPreScaleConvert   =      \
280             ByteGrayToIntArgbScaleConvert
281#endif
282
283#else
284
285void ADD_SUFF(ByteGrayToIntArgbPreConvert)(BLIT_PARAMS)
286{
287    ADD_SUFF(ByteGrayToIntArgbConvert)(BLIT_CALL_PARAMS);
288}
289
290void ADD_SUFF(ByteGrayToIntArgbPreScaleConvert)(SCALE_PARAMS)
291{
292    ADD_SUFF(ByteGrayToIntArgbScaleConvert)(SCALE_CALL_PARAMS);
293}
294
295#endif
296
297/***************************************************************/
298
299void ADD_SUFF(UshortGrayToByteGrayScaleConvert)(SCALE_PARAMS)
300{
301    mlib_s32 srcScan = pSrcInfo->scanStride;
302    mlib_s32 dstScan = pDstInfo->scanStride;
303    mlib_s32 i, j, w, tmpsxloc;
304
305    for (j = 0; j < height; j++) {
306        mlib_u8 *pSrc = srcBase;
307        mlib_u8 *pDst = dstBase;
308
309        tmpsxloc = sxloc;
310        w = width;
311
312        PTR_ADD(pSrc, (syloc >> shift) * srcScan);
313
314        if ((mlib_s32)pDst & 1) {
315            *pDst++ = pSrc[2*(tmpsxloc >> shift)];
316            tmpsxloc += sxinc;
317            w--;
318        }
319
320#pragma pipeloop(0)
321        for (i = 0; i <= (w - 2); i += 2) {
322            mlib_s32 x0, x1;
323            x0 = pSrc[2*(tmpsxloc >> shift)];
324            x1 = pSrc[2*((tmpsxloc + sxinc) >> shift)];
325            *(mlib_u16*)pDst = (x0 << 8) | x1;
326            pDst += 2;
327            tmpsxloc += 2*sxinc;
328        }
329
330        if (i < w) {
331            *pDst = pSrc[2*(tmpsxloc >> shift)];
332        }
333
334        PTR_ADD(dstBase, dstScan);
335        syloc += syinc;
336    }
337}
338
339/***************************************************************/
340
341void ADD_SUFF(Index8GrayToByteGrayConvert)(BLIT_PARAMS)
342{
343    jint *SrcReadLut = pSrcInfo->lutBase;
344    mlib_u8 *LutU8 = (mlib_u8*)SrcReadLut + 3;
345    mlib_s32 dstScan = pDstInfo->scanStride;
346    mlib_s32 srcScan = pSrcInfo->scanStride;
347    mlib_s32 i, j;
348
349    if (width < 8) {
350        for (j = 0; j < height; j++) {
351            Index8GrayDataType *src = srcBase;
352            mlib_u8 *dst = dstBase;
353
354            for (i = 0; i < width; i++) {
355                dst[i] = LUT(src[i]);
356            }
357
358            PTR_ADD(dstBase, dstScan);
359            PTR_ADD(srcBase, srcScan);
360        }
361        return;
362    }
363
364    if (srcScan == width && dstScan == width) {
365        width *= height;
366        height = 1;
367    }
368
369    for (j = 0; j < height; j++) {
370        Index8GrayDataType *src = srcBase;
371        mlib_u8 *dst = dstBase;
372        mlib_u8 *dst_end = dst + width;
373
374        if ((mlib_s32)dst & 1) {
375            *dst++ = LUT(*src);
376            src++;
377        }
378
379#pragma pipeloop(0)
380        for (; dst <= (dst_end - 2); dst += 2) {
381            ((mlib_u16*)dst)[0] = (LUT(src[0]) << 8) | LUT(src[1]);
382            src += 2;
383        }
384
385        if (dst < dst_end) {
386            *dst++ = LUT(*src);
387            src++;
388        }
389
390        PTR_ADD(dstBase, dstScan);
391        PTR_ADD(srcBase, srcScan);
392    }
393}
394
395/***************************************************************/
396
397void ADD_SUFF(Index12GrayToByteGrayConvert)(BLIT_PARAMS)
398{
399    jint *SrcReadLut = pSrcInfo->lutBase;
400    mlib_u8 *LutU8 = (mlib_u8*)SrcReadLut + 3;
401    mlib_s32 dstScan = pDstInfo->scanStride;
402    mlib_s32 srcScan = pSrcInfo->scanStride;
403    mlib_s32 i, j;
404
405    if (width < 8) {
406        for (j = 0; j < height; j++) {
407            Index12GrayDataType *src = srcBase;
408            mlib_u8 *dst = dstBase;
409
410            for (i = 0; i < width; i++) {
411                dst[i] = LUT12(src[i]);
412            }
413
414            PTR_ADD(dstBase, dstScan);
415            PTR_ADD(srcBase, srcScan);
416        }
417        return;
418    }
419
420    if (srcScan == 2*width && dstScan == width) {
421        width *= height;
422        height = 1;
423    }
424
425    for (j = 0; j < height; j++) {
426        Index12GrayDataType *src = srcBase;
427        mlib_u8 *dst = dstBase;
428        mlib_u8 *dst_end = dst + width;
429
430        if ((mlib_s32)dst & 1) {
431            *dst++ = LUT12(*src);
432            src++;
433        }
434
435#pragma pipeloop(0)
436        for (; dst <= (dst_end - 2); dst += 2) {
437            ((mlib_u16*)dst)[0] = (LUT12(src[0]) << 8) | LUT12(src[1]);
438            src += 2;
439        }
440
441        if (dst < dst_end) {
442            *dst++ = LUT12(*src);
443            src++;
444        }
445
446        PTR_ADD(dstBase, dstScan);
447        PTR_ADD(srcBase, srcScan);
448    }
449}
450
451/***************************************************************/
452
453void ADD_SUFF(Index8GrayToByteGrayScaleConvert)(SCALE_PARAMS)
454{
455    jint *SrcReadLut = pSrcInfo->lutBase;
456    mlib_u8 *LutU8 = (mlib_u8*)SrcReadLut + 3;
457    mlib_s32 dstScan = pDstInfo->scanStride;
458    mlib_s32 srcScan = pSrcInfo->scanStride;
459    mlib_s32 i, j;
460
461    if (width < 8) {
462        for (j = 0; j < height; j++) {
463            Index8GrayDataType *src = srcBase;
464            mlib_u8 *dst = dstBase;
465            jint  tmpsxloc = sxloc;
466
467            PTR_ADD(src, (syloc >> shift) * srcScan);
468
469            for (i = 0; i < width; i++) {
470                dst[i] = LUT(src[tmpsxloc >> shift]);
471                tmpsxloc += sxinc;
472            }
473
474            PTR_ADD(dstBase, dstScan);
475            syloc += syinc;
476        }
477        return;
478    }
479
480    for (j = 0; j < height; j++) {
481        Index8GrayDataType *src = srcBase;
482        mlib_u8 *dst = dstBase;
483        mlib_u8 *dst_end = dst + width;
484        jint  tmpsxloc = sxloc;
485
486        PTR_ADD(src, (syloc >> shift) * srcScan);
487
488        if ((mlib_s32)dst & 1) {
489            *dst++ = LUT(src[tmpsxloc >> shift]);
490            tmpsxloc += sxinc;
491        }
492
493#pragma pipeloop(0)
494        for (; dst <= (dst_end - 2); dst += 2) {
495            ((mlib_u16*)dst)[0] = (LUT(src[tmpsxloc >> shift]) << 8) |
496            LUT(src[(tmpsxloc + sxinc) >> shift]);
497            tmpsxloc += 2*sxinc;
498        }
499
500        if (dst < dst_end) {
501            *dst = LUT(src[tmpsxloc >> shift]);
502        }
503
504        PTR_ADD(dstBase, dstScan);
505        syloc += syinc;
506    }
507}
508
509/***************************************************************/
510
511void ADD_SUFF(Index12GrayToByteGrayScaleConvert)(SCALE_PARAMS)
512{
513    jint *SrcReadLut = pSrcInfo->lutBase;
514    mlib_u8 *LutU8 = (mlib_u8*)SrcReadLut + 3;
515    mlib_s32 dstScan = pDstInfo->scanStride;
516    mlib_s32 srcScan = pSrcInfo->scanStride;
517    mlib_s32 i, j;
518
519    if (width < 8) {
520        for (j = 0; j < height; j++) {
521            Index12GrayDataType *src = srcBase;
522            mlib_u8 *dst = dstBase;
523            jint  tmpsxloc = sxloc;
524
525            PTR_ADD(src, (syloc >> shift) * srcScan);
526
527            for (i = 0; i < width; i++) {
528                dst[i] = LUT12(src[tmpsxloc >> shift]);
529                tmpsxloc += sxinc;
530            }
531
532            PTR_ADD(dstBase, dstScan);
533            syloc += syinc;
534        }
535        return;
536    }
537
538    for (j = 0; j < height; j++) {
539        Index12GrayDataType *src = srcBase;
540        mlib_u8 *dst = dstBase;
541        mlib_u8 *dst_end = dst + width;
542        jint  tmpsxloc = sxloc;
543
544        PTR_ADD(src, (syloc >> shift) * srcScan);
545
546        if ((mlib_s32)dst & 1) {
547            *dst++ = LUT12(src[tmpsxloc >> shift]);
548            tmpsxloc += sxinc;
549        }
550
551#pragma pipeloop(0)
552        for (; dst <= (dst_end - 2); dst += 2) {
553            ((mlib_u16*)dst)[0] = (LUT12(src[tmpsxloc >> shift]) << 8) |
554            LUT12(src[(tmpsxloc + sxinc) >> shift]);
555            tmpsxloc += 2*sxinc;
556        }
557
558        if (dst < dst_end) {
559            *dst = LUT12(src[tmpsxloc >> shift]);
560        }
561
562        PTR_ADD(dstBase, dstScan);
563        syloc += syinc;
564    }
565}
566
567/***************************************************************/
568
569void ADD_SUFF(ByteIndexedToByteGrayConvert)(BLIT_PARAMS)
570{
571    jint  *srcLut = pSrcInfo->lutBase;
572    juint lutSize = pSrcInfo->lutSize;
573    mlib_u8  LutU8[256];
574    mlib_s32 dstScan = pDstInfo->scanStride;
575    mlib_s32 srcScan = pSrcInfo->scanStride;
576    mlib_s32 i, j;
577
578    if (width < 8) {
579        for (j = 0; j < height; j++) {
580            mlib_u8 *src = srcBase;
581            mlib_u8 *dst = dstBase;
582
583            for (i = 0; i < width; i++) {
584                jint argb = srcLut[src[i]];
585                int r, g, b;
586                b = (argb) & 0xff;
587                g = (argb >> 8) & 0xff;
588                r = (argb >> 16) & 0xff;
589                dst[i] = RGB2GRAY(r, g, b);
590            }
591
592            PTR_ADD(dstBase, dstScan);
593            PTR_ADD(srcBase, srcScan);
594        }
595        return;
596
597    }
598
599    if (lutSize >= 256) lutSize = 256;
600
601    ADD_SUFF(IntArgbToByteGrayConvert)(srcLut, LutU8, lutSize, 1,
602                                       pSrcInfo, pDstInfo, pPrim, pCompInfo);
603
604    for (i = lutSize; i < 256; i++) {
605        LutU8[i] = 0;
606    }
607
608    if (srcScan == width && dstScan == width) {
609        width *= height;
610        height = 1;
611    }
612
613    for (j = 0; j < height; j++) {
614        mlib_u8 *src = srcBase;
615        mlib_u8 *dst = dstBase;
616        mlib_u8 *dst_end = dst + width;
617
618        if ((mlib_s32)dst & 1) {
619            *dst++ = LutU8[*src];
620            src++;
621        }
622
623#pragma pipeloop(0)
624        for (; dst <= (dst_end - 2); dst += 2) {
625            ((mlib_u16*)dst)[0] = (LutU8[src[0]] << 8) | LutU8[src[1]];
626            src += 2;
627        }
628
629        if (dst < dst_end) {
630            *dst++ = LutU8[*src];
631            src++;
632        }
633
634        PTR_ADD(dstBase, dstScan);
635        PTR_ADD(srcBase, srcScan);
636    }
637}
638
639/***************************************************************/
640
641void ADD_SUFF(ByteIndexedToByteGrayScaleConvert)(SCALE_PARAMS)
642{
643    jint  *srcLut = pSrcInfo->lutBase;
644    juint lutSize = pSrcInfo->lutSize;
645    mlib_u8  LutU8[256];
646    mlib_s32 dstScan = pDstInfo->scanStride;
647    mlib_s32 srcScan = pSrcInfo->scanStride;
648    mlib_s32 i, j;
649
650    if (width < 8) {
651        for (j = 0; j < height; j++) {
652            mlib_u8 *src = srcBase;
653            mlib_u8 *dst = dstBase;
654            jint  tmpsxloc = sxloc;
655
656            PTR_ADD(src, (syloc >> shift) * srcScan);
657
658            for (i = 0; i < width; i++) {
659                jint argb = srcLut[src[tmpsxloc >> shift]];
660                int r, g, b;
661                b = (argb) & 0xff;
662                g = (argb >> 8) & 0xff;
663                r = (argb >> 16) & 0xff;
664                dst[i] = RGB2GRAY(r, g, b);
665                tmpsxloc += sxinc;
666            }
667
668            PTR_ADD(dstBase, dstScan);
669            syloc += syinc;
670        }
671        return;
672
673    }
674
675    if (lutSize >= 256) lutSize = 256;
676
677    ADD_SUFF(IntArgbToByteGrayConvert)(srcLut, LutU8, lutSize, 1,
678                                       pSrcInfo, pDstInfo, pPrim, pCompInfo);
679
680    for (i = lutSize; i < 256; i++) {
681        LutU8[i] = 0;
682    }
683
684    for (j = 0; j < height; j++) {
685        mlib_u8 *src = srcBase;
686        mlib_u8 *dst = dstBase;
687        mlib_u8 *dst_end = dst + width;
688        jint  tmpsxloc = sxloc;
689
690        PTR_ADD(src, (syloc >> shift) * srcScan);
691
692        if ((mlib_s32)dst & 1) {
693            *dst++ = LutU8[src[tmpsxloc >> shift]];
694            tmpsxloc += sxinc;
695        }
696
697#pragma pipeloop(0)
698        for (; dst <= (dst_end - 2); dst += 2) {
699            ((mlib_u16*)dst)[0] = (LutU8[src[tmpsxloc >> shift]] << 8) |
700                                   LutU8[src[(tmpsxloc + sxinc) >> shift]];
701            tmpsxloc += 2*sxinc;
702        }
703
704        if (dst < dst_end) {
705            *dst = LutU8[src[tmpsxloc >> shift]];
706        }
707
708        PTR_ADD(dstBase, dstScan);
709        syloc += syinc;
710    }
711}
712
713/***************************************************************/
714
715void ADD_SUFF(ByteIndexedBmToByteGrayXparOver)(BLIT_PARAMS)
716{
717    jint  *srcLut = pSrcInfo->lutBase;
718    juint lutSize = pSrcInfo->lutSize;
719    mlib_u8  LutU8[256];
720    mlib_u32 LutU32[256];
721    mlib_s32 dstScan = pDstInfo->scanStride;
722    mlib_s32 srcScan = pSrcInfo->scanStride;
723    mlib_s32 i, j, x0, x1, mask, res;
724
725    if (width < 16) {
726        for (j = 0; j < height; j++) {
727            mlib_u8 *src = srcBase;
728            mlib_u8 *dst = dstBase;
729
730            for (i = 0; i < width; i++) {
731                mlib_s32 argb = srcLut[src[i]];
732                if (argb < 0) {
733                    int r, g, b;
734                    b = (argb) & 0xff;
735                    g = (argb >> 8) & 0xff;
736                    r = (argb >> 16) & 0xff;
737                    dst[i] = RGB2GRAY(r, g, b);
738                }
739            }
740
741            PTR_ADD(dstBase, dstScan);
742            PTR_ADD(srcBase, srcScan);
743        }
744        return;
745    }
746
747    if (lutSize >= 256) lutSize = 256;
748
749    ADD_SUFF(IntArgbToByteGrayConvert)(srcLut, LutU8, lutSize, 1,
750                                       pSrcInfo, pDstInfo, pPrim, pCompInfo);
751
752    for (i = lutSize; i < 256; i++) {
753        LutU8[i] = 0;
754    }
755
756#pragma pipeloop(0)
757    for (i = 0; i < 256; i++) {
758        LutU32[i] = ((srcLut[i] >> 31) & 0xFF0000) | LutU8[i];
759    }
760
761    if (srcScan == width && dstScan == width) {
762        width *= height;
763        height = 1;
764    }
765
766    for (j = 0; j < height; j++) {
767        mlib_u8 *src = srcBase;
768        mlib_u8 *dst = dstBase;
769        mlib_u8 *dst_end = dst + width;
770
771        if ((mlib_s32)dst & 1) {
772            x0 = *src;
773            res = LutU32[x0];
774            mask = res >> 16;
775            *dst++ = (res & mask) | (*dst &~ mask);
776            src++;
777        }
778
779#pragma pipeloop(0)
780        for (; dst <= (dst_end - 2); dst += 2) {
781            x0 = src[0];
782            x1 = src[1];
783            res = (LutU32[x0] << 8) | LutU32[x1];
784            mask = res >> 16;
785            ((mlib_u16*)dst)[0] = (res & mask) | (((mlib_u16*)dst)[0] &~ mask);
786            src += 2;
787        }
788
789        if (dst < dst_end) {
790            x0 = *src;
791            res = LutU32[x0];
792            mask = res >> 16;
793            *dst = (res & mask) | (*dst &~ mask);
794        }
795
796        PTR_ADD(dstBase, dstScan);
797        PTR_ADD(srcBase, srcScan);
798    }
799}
800
801/***************************************************************/
802
803void ADD_SUFF(ByteIndexedBmToByteGrayXparBgCopy)(BCOPY_PARAMS)
804{
805    jint  *srcLut = pSrcInfo->lutBase;
806    juint lutSize = pSrcInfo->lutSize;
807    mlib_u8  LutU8[256];
808    mlib_s32 dstScan = pDstInfo->scanStride;
809    mlib_s32 srcScan = pSrcInfo->scanStride;
810    mlib_s32 i, j;
811
812    if (width < 16) {
813        for (j = 0; j < height; j++) {
814            mlib_u8 *src = srcBase;
815            mlib_u8 *dst = dstBase;
816
817            for (i = 0; i < width; i++) {
818                mlib_s32 argb = srcLut[src[i]];
819                if (argb < 0) {
820                    int r, g, b;
821                    b = (argb) & 0xff;
822                    g = (argb >> 8) & 0xff;
823                    r = (argb >> 16) & 0xff;
824                    dst[i] = RGB2GRAY(r, g, b);
825                } else {
826                    dst[i] = bgpixel;
827                }
828            }
829
830            PTR_ADD(dstBase, dstScan);
831            PTR_ADD(srcBase, srcScan);
832        }
833        return;
834    }
835
836    if (lutSize >= 256) lutSize = 256;
837
838    ADD_SUFF(IntArgbToByteGrayConvert)(srcLut, LutU8, lutSize, 1,
839                                       pSrcInfo, pDstInfo, pPrim, pCompInfo);
840
841    for (i = lutSize; i < 256; i++) {
842        LutU8[i] = 0;
843    }
844
845#pragma pipeloop(0)
846    for (i = 0; i < 256; i++) {
847        if (srcLut[i] >= 0) LutU8[i] = bgpixel;
848    }
849
850    if (srcScan == width && dstScan == width) {
851        width *= height;
852        height = 1;
853    }
854
855    for (j = 0; j < height; j++) {
856        mlib_u8 *src = srcBase;
857        mlib_u8 *dst = dstBase;
858        mlib_u8 *dst_end = dst + width;
859
860        if ((mlib_s32)dst & 1) {
861            *dst++ = LutU8[*src];
862            src++;
863        }
864
865#pragma pipeloop(0)
866        for (; dst <= (dst_end - 2); dst += 2) {
867            ((mlib_u16*)dst)[0] = (LutU8[src[0]] << 8) | LutU8[src[1]];
868            src += 2;
869        }
870
871        if (dst < dst_end) {
872            *dst++ = LutU8[*src];
873            src++;
874        }
875
876        PTR_ADD(dstBase, dstScan);
877        PTR_ADD(srcBase, srcScan);
878    }
879}
880
881/***************************************************************/
882
883void ADD_SUFF(ByteIndexedBmToByteGrayScaleXparOver)(SCALE_PARAMS)
884{
885    jint  *srcLut = pSrcInfo->lutBase;
886    juint lutSize = pSrcInfo->lutSize;
887    mlib_u8  LutU8[256];
888    mlib_u32 LutU32[256];
889    mlib_s32 dstScan = pDstInfo->scanStride;
890    mlib_s32 srcScan = pSrcInfo->scanStride;
891    mlib_s32 i, j, x0, x1, mask, res;
892
893    if (width < 16) {
894        for (j = 0; j < height; j++) {
895            mlib_u8 *src = srcBase;
896            mlib_u8 *dst = dstBase;
897            jint  tmpsxloc = sxloc;
898
899            PTR_ADD(src, (syloc >> shift) * srcScan);
900
901            for (i = 0; i < width; i++) {
902                mlib_s32 argb = srcLut[src[tmpsxloc >> shift]];
903                if (argb < 0) {
904                    int r, g, b;
905                    b = (argb) & 0xff;
906                    g = (argb >> 8) & 0xff;
907                    r = (argb >> 16) & 0xff;
908                    dst[i] = RGB2GRAY(r, g, b);
909                }
910                tmpsxloc += sxinc;
911            }
912
913            PTR_ADD(dstBase, dstScan);
914            syloc += syinc;
915        }
916        return;
917    }
918
919    if (lutSize >= 256) lutSize = 256;
920
921    ADD_SUFF(IntArgbToByteGrayConvert)(srcLut, LutU8, lutSize, 1,
922                                       pSrcInfo, pDstInfo, pPrim, pCompInfo);
923
924    for (i = lutSize; i < 256; i++) {
925        LutU8[i] = 0;
926    }
927
928#pragma pipeloop(0)
929    for (i = 0; i < 256; i++) {
930        LutU32[i] = ((srcLut[i] >> 31) & 0xFF0000) | LutU8[i];
931    }
932
933    for (j = 0; j < height; j++) {
934        mlib_u8 *src = srcBase;
935        mlib_u8 *dst = dstBase;
936        mlib_u8 *dst_end = dst + width;
937        jint  tmpsxloc = sxloc;
938
939        PTR_ADD(src, (syloc >> shift) * srcScan);
940
941        if ((mlib_s32)dst & 1) {
942            x0 = src[tmpsxloc >> shift];
943            res = LutU32[x0];
944            mask = res >> 16;
945            *dst++ = (res & mask) | (*dst &~ mask);
946            tmpsxloc += sxinc;
947        }
948
949#pragma pipeloop(0)
950        for (; dst <= (dst_end - 2); dst += 2) {
951            x0 = src[tmpsxloc >> shift];
952            x1 = src[(tmpsxloc + sxinc) >> shift];
953            res = (LutU32[x0] << 8) | LutU32[x1];
954            mask = res >> 16;
955            ((mlib_u16*)dst)[0] = (res & mask) | (((mlib_u16*)dst)[0] &~ mask);
956            tmpsxloc += 2*sxinc;
957        }
958
959        if (dst < dst_end) {
960            x0 = src[tmpsxloc >> shift];
961            res = LutU32[x0];
962            mask = res >> 16;
963            *dst = (res & mask) | (*dst &~ mask);
964        }
965
966        PTR_ADD(dstBase, dstScan);
967        syloc += syinc;
968    }
969}
970
971/***************************************************************/
972
973#endif
974