blob: 99d9ca6a5275501df6ee45fac8625b3bb099369f [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26
27/*
28 * FUNCTION
29 * mlib_ImageThresh1 - thresholding
30 *
31 * SYNOPSIS
32 * mlib_status mlib_ImageThresh1(mlib_image *dst,
33 * const mlib_image *src,
34 * const mlib_s32 *thresh,
35 * const mlib_s32 *ghigh,
36 * const mlib_s32 *glow);
37 *
38 * ARGUMENT
39 * dst pointer to output image
40 * src pointer to input image
41 * thresh array of thresholds
42 * ghigh array of values above thresholds
43 * glow array of values below thresholds
44 *
45 * RESTRICTION
46 * The images must have the same size, and the same number
47 * of channels.
48 * The images can have 1, 2, 3, or 4 channels.
49 * The images can be in MLIB_BYTE, MLIB_SHORT or MLIB_INT data type.
50 * The type of the output image can be MLIB_BIT, or the same as the
51 * type of the input image.
52 *
53 * DESCRIPTION
54 * If the pixel band value is above the threshold for that channel,
55 * set the destination to the ghigh value for that channel.
56 * Otherwise, set the destination to the glow value for that channel.
57 *
58 * +- glow[c] src[x][y][c] <= thresh[c]
59 * dst[x][y][c] = |
60 * +- ghigh[c] src[x][y][c] > thresh[c]
61 */
62
63#include "mlib_image.h"
64#include "mlib_ImageCheck.h"
65#include "mlib_c_ImageThresh1.h"
66
67/***************************************************************/
68#define STYPE mlib_u8
69#define TTYPE mlib_s32
70#define T_SHIFT 31
71
72/***************************************************************/
73#define DO_THRESH(s0, th, gl, gh) \
74 (((gh) & (((th) - (TTYPE)(s0)) >> T_SHIFT)) | \
75 ((gl) &~ (((th) - (TTYPE)(s0)) >> T_SHIFT)))
76
77/***************************************************************/
78#define THRESH1_CMP_SHIFT(s0, th, sh) \
79 ((((th) - (s0)) >> T_SHIFT) & (1 << (sh)))
80
81/***************************************************************/
82#define STRIP(pd, ps, w, h, ch, th, gh, gl) { \
83 STYPE s0; \
84 for ( i = 0; i < h; i++ ) { \
85 for (j = 0; j < w; j ++) { \
86 for (k = 0; k < ch; k++) { \
87 s0 = ((STYPE*)ps)[i*src_stride + j*ch + k]; \
88 ((STYPE*)pd)[i*dst_stride + j*ch + k] = \
89 (s0 <= th[k]) ? gl[k]: gh[k]; \
90 } \
91 } \
92 } \
93 }
94
95/***************************************************************/
96#define INIT_THRESH0(n) \
97 thresh0 = thresh[n]; \
98 ghigh0 = ghigh[n]; \
99 glow0 = glow[n]
100
101/***************************************************************/
102#define INIT_THRESH1(n) \
103 thresh1 = thresh[n]; \
104 ghigh1 = ghigh[n]; \
105 glow1 = glow[n]
106
107/***************************************************************/
108#define INIT_THRESH2(n) \
109 thresh2 = thresh[n]; \
110 ghigh2 = ghigh[n]; \
111 glow2 = glow[n]
112
113/***************************************************************/
114#define INIT_THRESH3(n) \
115 thresh3 = thresh[n]; \
116 ghigh3 = ghigh[n]; \
117 glow3 = glow[n]
118
119/***************************************************************/
120#define THRESH0(s0) DO_THRESH(s0, thresh0, glow0, ghigh0)
121#define THRESH1(s0) DO_THRESH(s0, thresh1, glow1, ghigh1)
122#define THRESH2(s0) DO_THRESH(s0, thresh2, glow2, ghigh2)
123#define THRESH3(s0) DO_THRESH(s0, thresh3, glow3, ghigh3)
124
125/***************************************************************/
126void mlib_c_ImageThresh1_U81(PARAMS)
127{
128 mlib_s32 *thresh = (void *)__thresh;
129 mlib_s32 *ghigh = (void *)__ghigh;
130 mlib_s32 *glow = (void *)__glow;
131 STYPE *psrc_row = psrc;
132 STYPE *pdst_row = pdst;
133 TTYPE thresh0;
134 TTYPE ghigh0;
135 TTYPE glow0;
136 mlib_s32 i, j, k;
137
138 if (width < 16) {
139 STRIP(pdst, psrc, width, height, 1, thresh, ghigh, glow);
140 return;
141 }
142
143 INIT_THRESH0(0);
144
145 for (i = 0; i < height; i++) {
146
147#ifdef __SUNPRO_C
148#pragma pipeloop(0)
149#endif /* __SUNPRO_C */
150 for (j = 0; j <= (width - 8); j += 8) {
151 pdst_row[j] = THRESH0(psrc_row[j]);
152 pdst_row[j + 1] = THRESH0(psrc_row[j + 1]);
153 pdst_row[j + 2] = THRESH0(psrc_row[j + 2]);
154 pdst_row[j + 3] = THRESH0(psrc_row[j + 3]);
155 pdst_row[j + 4] = THRESH0(psrc_row[j + 4]);
156 pdst_row[j + 5] = THRESH0(psrc_row[j + 5]);
157 pdst_row[j + 6] = THRESH0(psrc_row[j + 6]);
158 pdst_row[j + 7] = THRESH0(psrc_row[j + 7]);
159 }
160
161 for (; j < width; j++) {
162 pdst_row[j] = THRESH0(psrc_row[j]);
163 }
164
165 psrc_row += src_stride;
166 pdst_row += dst_stride;
167 }
168}
169
170/***************************************************************/
171void mlib_c_ImageThresh1_U82(PARAMS)
172{
173 mlib_s32 *thresh = (void *)__thresh;
174 mlib_s32 *ghigh = (void *)__ghigh;
175 mlib_s32 *glow = (void *)__glow;
176 STYPE *psrc_row = psrc;
177 STYPE *pdst_row = pdst;
178 TTYPE thresh0, thresh1;
179 TTYPE ghigh0, ghigh1;
180 TTYPE glow0, glow1;
181 mlib_s32 i, j, k;
182
183 if (width < 16) {
184 STRIP(pdst, psrc, width, height, 2, thresh, ghigh, glow);
185 return;
186 }
187
188 INIT_THRESH0(0);
189 INIT_THRESH1(1);
190 width <<= 1;
191
192 for (i = 0; i < height; i++) {
193
194#ifdef __SUNPRO_C
195#pragma pipeloop(0)
196#endif /* __SUNPRO_C */
197 for (j = 0; j <= (width - 8); j += 8) {
198 pdst_row[j] = THRESH0(psrc_row[j]);
199 pdst_row[j + 1] = THRESH1(psrc_row[j + 1]);
200 pdst_row[j + 2] = THRESH0(psrc_row[j + 2]);
201 pdst_row[j + 3] = THRESH1(psrc_row[j + 3]);
202 pdst_row[j + 4] = THRESH0(psrc_row[j + 4]);
203 pdst_row[j + 5] = THRESH1(psrc_row[j + 5]);
204 pdst_row[j + 6] = THRESH0(psrc_row[j + 6]);
205 pdst_row[j + 7] = THRESH1(psrc_row[j + 7]);
206 }
207
208 for (; j < width; j += 2) {
209 pdst_row[j] = THRESH0(psrc_row[j]);
210 pdst_row[j + 1] = THRESH1(psrc_row[j + 1]);
211 }
212
213 psrc_row += src_stride;
214 pdst_row += dst_stride;
215 }
216}
217
218/***************************************************************/
219void mlib_c_ImageThresh1_U83(PARAMS)
220{
221 mlib_s32 *thresh = (void *)__thresh;
222 mlib_s32 *ghigh = (void *)__ghigh;
223 mlib_s32 *glow = (void *)__glow;
224 STYPE *psrc_row = psrc;
225 STYPE *pdst_row = pdst;
226 TTYPE thresh0, thresh1, thresh2;
227 TTYPE ghigh0, ghigh1, ghigh2;
228 TTYPE glow0, glow1, glow2;
229 mlib_s32 i, j, k;
230
231 if (width < 16) {
232 STRIP(pdst, psrc, width, height, 3, thresh, ghigh, glow);
233 return;
234 }
235
236 width = 3 * width;
237 INIT_THRESH0(0);
238 INIT_THRESH1(1);
239 INIT_THRESH2(2);
240
241 for (i = 0; i < height; i++) {
242
243#ifdef __SUNPRO_C
244#pragma pipeloop(0)
245#endif /* __SUNPRO_C */
246 for (j = 0; j <= (width - 12); j += 12) {
247 pdst_row[j] = THRESH0(psrc_row[j]);
248 pdst_row[j + 1] = THRESH1(psrc_row[j + 1]);
249 pdst_row[j + 2] = THRESH2(psrc_row[j + 2]);
250 pdst_row[j + 3] = THRESH0(psrc_row[j + 3]);
251 pdst_row[j + 4] = THRESH1(psrc_row[j + 4]);
252 pdst_row[j + 5] = THRESH2(psrc_row[j + 5]);
253 pdst_row[j + 6] = THRESH0(psrc_row[j + 6]);
254 pdst_row[j + 7] = THRESH1(psrc_row[j + 7]);
255 pdst_row[j + 8] = THRESH2(psrc_row[j + 8]);
256 pdst_row[j + 9] = THRESH0(psrc_row[j + 9]);
257 pdst_row[j + 10] = THRESH1(psrc_row[j + 10]);
258 pdst_row[j + 11] = THRESH2(psrc_row[j + 11]);
259 }
260
261 for (; j < width; j += 3) {
262 pdst_row[j] = THRESH0(psrc_row[j]);
263 pdst_row[j + 1] = THRESH1(psrc_row[j + 1]);
264 pdst_row[j + 2] = THRESH2(psrc_row[j + 2]);
265 }
266
267 psrc_row += src_stride;
268 pdst_row += dst_stride;
269 }
270}
271
272/***************************************************************/
273void mlib_c_ImageThresh1_U84(PARAMS)
274{
275 mlib_s32 *thresh = (void *)__thresh;
276 mlib_s32 *ghigh = (void *)__ghigh;
277 mlib_s32 *glow = (void *)__glow;
278 STYPE *psrc_row = psrc;
279 STYPE *pdst_row = pdst;
280 TTYPE thresh0, thresh1, thresh2, thresh3;
281 TTYPE ghigh0, ghigh1, ghigh2, ghigh3;
282 TTYPE glow0, glow1, glow2, glow3;
283 mlib_s32 i, j, k;
284
285 if (width < 16) {
286 STRIP(pdst, psrc, width, height, 4, thresh, ghigh, glow);
287 return;
288 }
289
290 INIT_THRESH0(0);
291 INIT_THRESH1(1);
292 INIT_THRESH2(2);
293 INIT_THRESH3(3);
294
295 width *= 4;
296
297 for (i = 0; i < height; i++) {
298
299#ifdef __SUNPRO_C
300#pragma pipeloop(0)
301#endif /* __SUNPRO_C */
302 for (j = 0; j <= (width - 8); j += 8) {
303 pdst_row[j] = THRESH0(psrc_row[j]);
304 pdst_row[j + 1] = THRESH1(psrc_row[j + 1]);
305 pdst_row[j + 2] = THRESH2(psrc_row[j + 2]);
306 pdst_row[j + 3] = THRESH3(psrc_row[j + 3]);
307 pdst_row[j + 4] = THRESH0(psrc_row[j + 4]);
308 pdst_row[j + 5] = THRESH1(psrc_row[j + 5]);
309 pdst_row[j + 6] = THRESH2(psrc_row[j + 6]);
310 pdst_row[j + 7] = THRESH3(psrc_row[j + 7]);
311 }
312
313 if (j < width) {
314 pdst_row[j] = THRESH0(psrc_row[j]);
315 pdst_row[j + 1] = THRESH1(psrc_row[j + 1]);
316 pdst_row[j + 2] = THRESH2(psrc_row[j + 2]);
317 pdst_row[j + 3] = THRESH3(psrc_row[j + 3]);
318 }
319
320 psrc_row += src_stride;
321 pdst_row += dst_stride;
322 }
323}
324
325/***************************************************************/
326void mlib_c_ImageThresh1_U81_1B(PARAMS,
327 mlib_s32 dbit_off)
328{
329 mlib_s32 *thresh = (void *)__thresh;
330 mlib_s32 *ghigh = (void *)__ghigh;
331 mlib_s32 *glow = (void *)__glow;
332 STYPE *psrc_row = psrc;
333 mlib_u8 *pdst_row = pdst;
334 TTYPE thresh0 = thresh[0];
335 mlib_s32 mhigh, mlow, emask, dst0;
336 mlib_s32 i, j, jbit, l;
337
338 mhigh = (ghigh[0] > 0) ? 0xff : 0;
339 mlow = (glow[0] > 0) ? 0xff : 0;
340
341 for (i = 0; i < height; i++) {
342 j = 0;
343 jbit = 0;
344
345 if (dbit_off) {
346 mlib_s32 nume = 8 - dbit_off;
347
348 if (nume > width)
349 nume = width;
350 dst0 = 0;
351 emask = 0;
352
353 for (; j < nume; j++) {
354 emask |= (1 << (7 - (dbit_off + j)));
355 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
356 }
357
358 dst0 = (mhigh & dst0) | (mlow & ~dst0);
359 pdst_row[0] = (dst0 & emask) | (pdst_row[0] & ~emask);
360 jbit++;
361 }
362
363#ifdef __SUNPRO_C
364#pragma pipeloop(0)
365#endif /* __SUNPRO_C */
366 for (; j <= (width - 16); j += 16) {
367 dst0 = THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
368 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh0, 6) |
369 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh0, 5) |
370 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh0, 4) |
371 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
372 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh0, 2) |
373 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh0, 1) |
374 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh0, 0);
375 dst0 = (mhigh & dst0) | (mlow & ~dst0);
376 *(pdst_row + jbit) = (mlib_u8) dst0;
377 jbit++;
378 dst0 = THRESH1_CMP_SHIFT(psrc_row[j + 8], thresh0, 7) |
379 THRESH1_CMP_SHIFT(psrc_row[j + 9], thresh0, 6) |
380 THRESH1_CMP_SHIFT(psrc_row[j + 10], thresh0, 5) |
381 THRESH1_CMP_SHIFT(psrc_row[j + 11], thresh0, 4) |
382 THRESH1_CMP_SHIFT(psrc_row[j + 12], thresh0, 3) |
383 THRESH1_CMP_SHIFT(psrc_row[j + 13], thresh0, 2) |
384 THRESH1_CMP_SHIFT(psrc_row[j + 14], thresh0, 1) |
385 THRESH1_CMP_SHIFT(psrc_row[j + 15], thresh0, 0);
386 dst0 = (mhigh & dst0) | (mlow & ~dst0);
387 *(pdst_row + jbit) = (mlib_u8) dst0;
388 jbit++;
389 }
390
391 if (width - j >= 8) {
392 dst0 = THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
393 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh0, 6) |
394 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh0, 5) |
395 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh0, 4) |
396 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
397 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh0, 2) |
398 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh0, 1) |
399 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh0, 0);
400 dst0 = (mhigh & dst0) | (mlow & ~dst0);
401 *(pdst_row + jbit) = (mlib_u8) dst0;
402 jbit++;
403 j += 8;
404 }
405
406 if (j < width) {
407 dst0 = 0;
408 l = 7;
409 for (; j < width; j++) {
410 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, l);
411 l--;
412 }
413
414 emask = (0xFF << (l + 1));
415 dst0 = (mhigh & dst0) | (mlow & ~dst0);
416 pdst_row[jbit] = (dst0 & emask) | (pdst_row[jbit] & ~emask);
417 }
418
419 psrc_row += src_stride;
420 pdst_row += dst_stride;
421 }
422}
423
424/***************************************************************/
425void mlib_c_ImageThresh1_U82_1B(PARAMS,
426 mlib_s32 dbit_off)
427{
428 mlib_s32 *thresh = (void *)__thresh;
429 mlib_s32 *ghigh = (void *)__ghigh;
430 mlib_s32 *glow = (void *)__glow;
431 STYPE *psrc_row = psrc;
432 mlib_u8 *pdst_row = pdst;
433 TTYPE thresh0 = thresh[0], thresh1 = thresh[1];
434 mlib_s32 mhigh0, mlow0, mhigh, mlow, emask, dst0;
435 mlib_s32 i, j, jbit, l;
436
437 mhigh0 = (ghigh[0] > 0) ? 0xaaa : 0;
438 mhigh0 |= (ghigh[1] > 0) ? 0x555 : 0;
439 mlow0 = (glow[0] > 0) ? 0xaaa : 0;
440 mlow0 |= (glow[1] > 0) ? 0x555 : 0;
441
442 width *= 2;
443
444 for (i = 0; i < height; i++) {
445 thresh0 = thresh[0];
446 thresh1 = thresh[1];
447
448 j = 0;
449 jbit = 0;
450 mhigh = mhigh0 >> (dbit_off & 1);
451 mlow = mlow0 >> (dbit_off & 1);
452
453 if (dbit_off) {
454 mlib_s32 nume = 8 - dbit_off;
455
456 if (nume > width)
457 nume = width;
458 dst0 = 0;
459 emask = 0;
460
461 for (; j <= (nume - 2); j += 2) {
462 emask |= (3 << (6 - (dbit_off + j)));
463 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
464 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6 - (dbit_off + j));
465 }
466
467 if (j < nume) {
468 emask |= (1 << (7 - (dbit_off + j)));
469 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
470 /* swap threshes */
471 thresh0 = thresh[1];
472 thresh1 = thresh[0];
473 j++;
474 }
475
476 dst0 = (mhigh & dst0) | (mlow & ~dst0);
477 pdst_row[0] = (dst0 & emask) | (pdst_row[0] & ~emask);
478 jbit++;
479 }
480
481#ifdef __SUNPRO_C
482#pragma pipeloop(0)
483#endif /* __SUNPRO_C */
484 for (; j <= (width - 16); j += 16) {
485 dst0 = THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
486 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6) |
487 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh0, 5) |
488 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh1, 4) |
489 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
490 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh1, 2) |
491 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh0, 1) |
492 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh1, 0);
493 dst0 = (mhigh & dst0) | (mlow & ~dst0);
494 *(pdst_row + jbit) = (mlib_u8) dst0;
495 jbit++;
496 dst0 = THRESH1_CMP_SHIFT(psrc_row[j + 8], thresh0, 7) |
497 THRESH1_CMP_SHIFT(psrc_row[j + 9], thresh1, 6) |
498 THRESH1_CMP_SHIFT(psrc_row[j + 10], thresh0, 5) |
499 THRESH1_CMP_SHIFT(psrc_row[j + 11], thresh1, 4) |
500 THRESH1_CMP_SHIFT(psrc_row[j + 12], thresh0, 3) |
501 THRESH1_CMP_SHIFT(psrc_row[j + 13], thresh1, 2) |
502 THRESH1_CMP_SHIFT(psrc_row[j + 14], thresh0, 1) |
503 THRESH1_CMP_SHIFT(psrc_row[j + 15], thresh1, 0);
504 dst0 = (mhigh & dst0) | (mlow & ~dst0);
505 *(pdst_row + jbit) = (mlib_u8) dst0;
506 jbit++;
507 }
508
509 if (width - j >= 8) {
510 dst0 = THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
511 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6) |
512 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh0, 5) |
513 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh1, 4) |
514 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
515 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh1, 2) |
516 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh0, 1) |
517 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh1, 0);
518 dst0 = (mhigh & dst0) | (mlow & ~dst0);
519 *(pdst_row + jbit) = (mlib_u8) dst0;
520 jbit++;
521 j += 8;
522 }
523
524 if (j < width) {
525 dst0 = 0;
526 l = 7;
527 for (; j <= (width - 2); j += 2) {
528 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, l);
529 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, l - 1);
530 l -= 2;
531 }
532
533 if (j < width) {
534 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, l);
535 l--;
536 }
537
538 emask = (0xFF << (l + 1));
539 dst0 = (mhigh & dst0) | (mlow & ~dst0);
540 pdst_row[jbit] = (dst0 & emask) | (pdst_row[jbit] & ~emask);
541 }
542
543 psrc_row += src_stride;
544 pdst_row += dst_stride;
545 }
546}
547
548/***************************************************************/
549void mlib_c_ImageThresh1_U83_1B(PARAMS,
550 mlib_s32 dbit_off)
551{
552 mlib_s32 *thresh = (void *)__thresh;
553 mlib_s32 *ghigh = (void *)__ghigh;
554 mlib_s32 *glow = (void *)__glow;
555 STYPE *psrc_row = psrc;
556 mlib_u8 *pdst_row = pdst;
557 TTYPE thresh0, thresh1, thresh2, threshT;
558 mlib_s32 mhigh = 0, mlow = 0;
559 mlib_s32 mhigh0, mlow0, mhigh1, mlow1, mhigh2, mlow2, emask, dst0, dst1;
560 mlib_s32 i, j, jbit, k, l;
561
562 if (ghigh[0] > 0)
563 mhigh = 0x492492;
564
565 if (ghigh[1] > 0)
566 mhigh |= 0x249249;
567
568 if (ghigh[2] > 0)
569 mhigh |= 0x924924;
570
571 if (glow[0] > 0)
572 mlow = 0x492492;
573
574 if (glow[1] > 0)
575 mlow |= 0x249249;
576
577 if (glow[2] > 0)
578 mlow |= 0x924924;
579
580 width = 3 * width;
581
582 for (i = 0; i < height; i++) {
583 thresh0 = thresh[0];
584 thresh1 = thresh[1];
585 thresh2 = thresh[2];
586
587 j = 0;
588 jbit = 0;
589 mhigh0 = mhigh >> (dbit_off & 7);
590 mlow0 = mlow >> (dbit_off & 7);
591 mhigh1 = mhigh0 >> 1;
592 mlow1 = mlow0 >> 1;
593 mhigh2 = mhigh0 >> 2;
594 mlow2 = mlow0 >> 2;
595
596 if (dbit_off) {
597 mlib_s32 nume = 8 - dbit_off;
598
599 if (nume > width)
600 nume = width;
601 dst0 = 0;
602 emask = 0;
603
604 for (; j <= (nume - 3); j += 3) {
605 emask |= (7 << (5 - (dbit_off + j)));
606 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
607 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6 - (dbit_off + j));
608 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, 5 - (dbit_off + j));
609 }
610
611 for (; j < nume; j++) {
612 emask |= (1 << (7 - (dbit_off + j)));
613 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
614 /* swap threshes */
615 threshT = thresh0;
616 thresh0 = thresh1;
617 thresh1 = thresh2;
618 thresh2 = threshT;
619 }
620
621 dst0 = (mhigh0 & dst0) | (mlow0 & ~dst0);
622 pdst_row[0] = (dst0 & emask) | (pdst_row[0] & ~emask);
623 jbit++;
624
625 mhigh0 = mhigh >> (9 - nume);
626 mlow0 = mlow >> (9 - nume);
627 mhigh1 = mhigh0 >> 1;
628 mlow1 = mlow0 >> 1;
629 mhigh2 = mhigh0 >> 2;
630 mlow2 = mlow0 >> 2;
631 }
632
633#ifdef __SUNPRO_C
634#pragma pipeloop(0)
635#endif /* __SUNPRO_C */
636 for (; j <= (width - 24); j += 24) {
637 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
638 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6) |
639 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, 5) |
640 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh0, 4) |
641 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh1, 3) |
642 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh2, 2) |
643 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh0, 1) |
644 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh1, 0));
645 dst0 = (mhigh0 & dst0) | (mlow0 & ~dst0);
646 *(pdst_row + jbit) = dst0;
647 jbit++;
648 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j + 8], thresh2, 7) |
649 THRESH1_CMP_SHIFT(psrc_row[j + 9], thresh0, 6) |
650 THRESH1_CMP_SHIFT(psrc_row[j + 10], thresh1, 5) |
651 THRESH1_CMP_SHIFT(psrc_row[j + 11], thresh2, 4) |
652 THRESH1_CMP_SHIFT(psrc_row[j + 12], thresh0, 3) |
653 THRESH1_CMP_SHIFT(psrc_row[j + 13], thresh1, 2) |
654 THRESH1_CMP_SHIFT(psrc_row[j + 14], thresh2, 1) |
655 THRESH1_CMP_SHIFT(psrc_row[j + 15], thresh0, 0));
656 dst0 = (mhigh1 & dst0) | (mlow1 & ~dst0);
657 *(pdst_row + jbit) = dst0;
658 jbit++;
659 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j + 16], thresh1, 7) |
660 THRESH1_CMP_SHIFT(psrc_row[j + 17], thresh2, 6) |
661 THRESH1_CMP_SHIFT(psrc_row[j + 18], thresh0, 5) |
662 THRESH1_CMP_SHIFT(psrc_row[j + 19], thresh1, 4) |
663 THRESH1_CMP_SHIFT(psrc_row[j + 20], thresh2, 3) |
664 THRESH1_CMP_SHIFT(psrc_row[j + 21], thresh0, 2) |
665 THRESH1_CMP_SHIFT(psrc_row[j + 22], thresh1, 1) |
666 THRESH1_CMP_SHIFT(psrc_row[j + 23], thresh2, 0));
667 dst0 = (mhigh2 & dst0) | (mlow2 & ~dst0);
668 *(pdst_row + jbit) = dst0;
669 jbit++;
670 }
671
672 if (j < width) {
673 k = width - j;
674 dst0 = 0;
675 l = 31;
676 for (; j < width; j += 3) {
677 dst0 |= (THRESH1_CMP_SHIFT(psrc_row[j], thresh0, l) |
678 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, l - 1) |
679 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, l - 2));
680 l -= 3;
681 }
682
683 l = (k + 7) >> 3;
684 k = (l << 3) - k;
685 emask = (0xFF << k);
686
687 if (l == 3) {
688 dst1 = dst0 >> 24;
689 dst1 = (mhigh0 & dst1) | (mlow0 & ~dst1);
690 pdst_row[jbit] = dst1;
691 dst1 = (dst0 >> 16);
692 dst1 = (mhigh1 & dst1) | (mlow1 & ~dst1);
693 pdst_row[jbit + 1] = dst1;
694 dst1 = (dst0 >> 8);
695 dst1 = (mhigh2 & dst1) | (mlow2 & ~dst1);
696 pdst_row[jbit + 2] = (dst1 & emask) | (pdst_row[jbit + 2] & ~emask);
697 }
698 else if (l == 2) {
699 dst1 = dst0 >> 24;
700 dst1 = (mhigh0 & dst1) | (mlow0 & ~dst1);
701 pdst_row[jbit] = dst1;
702 dst1 = (dst0 >> 16);
703 dst1 = (mhigh1 & dst1) | (mlow1 & ~dst1);
704 pdst_row[jbit + 1] = (dst1 & emask) | (pdst_row[jbit + 1] & ~emask);
705 }
706 else {
707 dst1 = dst0 >> 24;
708 dst1 = (mhigh0 & dst1) | (mlow0 & ~dst1);
709 pdst_row[jbit] = (dst1 & emask) | (pdst_row[jbit] & ~emask);
710 }
711 }
712
713 psrc_row += src_stride;
714 pdst_row += dst_stride;
715 }
716}
717
718/***************************************************************/
719void mlib_c_ImageThresh1_U84_1B(PARAMS,
720 mlib_s32 dbit_off)
721{
722 mlib_s32 *thresh = (void *)__thresh;
723 mlib_s32 *ghigh = (void *)__ghigh;
724 mlib_s32 *glow = (void *)__glow;
725 STYPE *psrc_row = psrc;
726 mlib_u8 *pdst_row = pdst;
727 TTYPE thresh0, thresh1, thresh2, thresh3, threshT;
728 mlib_s32 mhigh0, mlow0, mhigh, mlow, emask, dst0;
729 mlib_s32 i, j, jbit;
730
731 mhigh0 = (ghigh[0] > 0) ? 0x8888 : 0;
732 mhigh0 |= (ghigh[1] > 0) ? 0x4444 : 0;
733 mhigh0 |= (ghigh[2] > 0) ? 0x2222 : 0;
734 mhigh0 |= (ghigh[3] > 0) ? 0x1111 : 0;
735
736 mlow0 = (glow[0] > 0) ? 0x8888 : 0;
737 mlow0 |= (glow[1] > 0) ? 0x4444 : 0;
738 mlow0 |= (glow[2] > 0) ? 0x2222 : 0;
739 mlow0 |= (glow[3] > 0) ? 0x1111 : 0;
740
741 width *= 4;
742
743 for (i = 0; i < height; i++) {
744 thresh0 = thresh[0];
745 thresh1 = thresh[1];
746 thresh2 = thresh[2];
747 thresh3 = thresh[3];
748
749 j = 0;
750 jbit = 0;
751 mhigh = mhigh0 >> dbit_off;
752 mlow = mlow0 >> dbit_off;
753
754 if (dbit_off) {
755 mlib_s32 nume = 8 - dbit_off;
756
757 if (nume > width)
758 nume = width;
759 dst0 = 0;
760 emask = 0;
761
762 for (; j <= (nume - 4); j += 4) {
763 emask |= (0xf << (4 - (dbit_off + j)));
764 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
765 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6 - (dbit_off + j));
766 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, 5 - (dbit_off + j));
767 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh3, 4 - (dbit_off + j));
768 }
769
770 for (; j < nume; j++) {
771 emask |= (1 << (7 - (dbit_off + j)));
772 dst0 |= THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7 - (dbit_off + j));
773 /* swap threshes */
774 threshT = thresh0;
775 thresh0 = thresh1;
776 thresh1 = thresh2;
777 thresh2 = thresh3;
778 thresh3 = threshT;
779 }
780
781 dst0 = (mhigh & dst0) | (mlow & ~dst0);
782 pdst_row[0] = (dst0 & emask) | (pdst_row[0] & ~emask);
783 jbit++;
784 }
785
786#ifdef __SUNPRO_C
787#pragma pipeloop(0)
788#endif /* __SUNPRO_C */
789 for (; j <= (width - 16); j += 16) {
790 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
791 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6) |
792 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, 5) |
793 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh3, 4) |
794 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
795 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh1, 2) |
796 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh2, 1) |
797 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh3, 0));
798 dst0 = (mhigh & dst0) | (mlow & ~dst0);
799 pdst_row[jbit] = dst0;
800 jbit++;
801 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j + 8], thresh0, 7) |
802 THRESH1_CMP_SHIFT(psrc_row[j + 9], thresh1, 6) |
803 THRESH1_CMP_SHIFT(psrc_row[j + 10], thresh2, 5) |
804 THRESH1_CMP_SHIFT(psrc_row[j + 11], thresh3, 4) |
805 THRESH1_CMP_SHIFT(psrc_row[j + 12], thresh0, 3) |
806 THRESH1_CMP_SHIFT(psrc_row[j + 13], thresh1, 2) |
807 THRESH1_CMP_SHIFT(psrc_row[j + 14], thresh2, 1) |
808 THRESH1_CMP_SHIFT(psrc_row[j + 15], thresh3, 0));
809 dst0 = (mhigh & dst0) | (mlow & ~dst0);
810 pdst_row[jbit] = dst0;
811 jbit++;
812 }
813
814 if (j <= width - 8) {
815 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
816 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6) |
817 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, 5) |
818 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh3, 4) |
819 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
820 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh1, 2) |
821 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh2, 1) |
822 THRESH1_CMP_SHIFT(psrc_row[j + 7], thresh3, 0));
823 dst0 = (mhigh & dst0) | (mlow & ~dst0);
824 pdst_row[jbit] = dst0;
825 jbit++;
826 j += 8;
827 }
828
829 if (j < width) {
830 dst0 = (THRESH1_CMP_SHIFT(psrc_row[j], thresh0, 7) |
831 THRESH1_CMP_SHIFT(psrc_row[j + 1], thresh1, 6) |
832 THRESH1_CMP_SHIFT(psrc_row[j + 2], thresh2, 5) |
833 THRESH1_CMP_SHIFT(psrc_row[j + 3], thresh3, 4) |
834 THRESH1_CMP_SHIFT(psrc_row[j + 4], thresh0, 3) |
835 THRESH1_CMP_SHIFT(psrc_row[j + 5], thresh1, 2) |
836 THRESH1_CMP_SHIFT(psrc_row[j + 6], thresh2, 1));
837
838 emask = (0xFF << (8 - (width - j)));
839 dst0 = (mhigh & dst0) | (mlow & ~dst0);
840 pdst_row[jbit] = (dst0 & emask) | (pdst_row[jbit] & ~emask);
841 }
842
843 psrc_row += src_stride;
844 pdst_row += dst_stride;
845 }
846}
847
848/***************************************************************/